Android创建前台运行的Service
Service如果要防止尽可能不被系统杀掉,需要设置为在前台运行。
由于设置前台运行service的方法在2.0之前和2.0之后有所变化。
所以需要根据不同的版本进行区分;或者完全使用反射机制来处理,这样只要有相应的方法就可以使用,否则使用其他版本的方法。
下面是一个设置servcie前台运行的例子,参考了API中对Service的说明。
http://developer.android.com/reference/android/app/Service.html#
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.Build.VERSION;
import android.util.Log;public class ForegroundService extends Service {private static final String TAG = "ForegroundService";private boolean mReflectFlg = false;private static final int NOTIFICATION_ID = 1; // 如果id设置为0,会导致不能设置为前台serviceprivate static final Class<?>[] mSetForegroundSignature = new Class[] {boolean.class};private static final Class<?>[] mStartForegroundSignature = new Class[] {int.class, Notification.class};private static final Class<?>[] mStopForegroundSignature = new Class[] {boolean.class};private NotificationManager mNM; private Method mSetForeground;private Method mStartForeground; private Method mStopForeground;private Object[] mSetForegroundArgs = new Object[1];private Object[] mStartForegroundArgs = new Object[2]; private Object[] mStopForegroundArgs = new Object[1]; @Override public void onCreate() { super.onCreate();Log.d(TAG, "onCreate");mNM = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); try { mStartForeground = ForegroundService.class.getMethod("startForeground", mStartForegroundSignature); mStopForeground = ForegroundService.class.getMethod("stopForeground", mStopForegroundSignature); } catch (NoSuchMethodException e) { mStartForeground = mStopForeground = null; } try {mSetForeground = getClass().getMethod("setForeground",mSetForegroundSignature);} catch (NoSuchMethodException e) {throw new IllegalStateException("OS doesn't have Service.startForeground OR Service.setForeground!");}Notification.Builder builder = new Notification.Builder(this);PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0); builder.setContentIntent(contentIntent);builder.setSmallIcon(R.drawable.icon);builder.setTicker("Foreground Service Start");builder.setContentTitle("Foreground Service");builder.setContentText("Make this service run in the foreground.");Notification notification = builder.build();startForegroundCompat(NOTIFICATION_ID, notification); } @Overridepublic int onStartCommand(Intent intent, int flags, int startId) {super.onStartCommand(intent, flags, startId);Log.d(TAG, "onStartCommand");return START_STICKY;} @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy();Log.d(TAG, "onDestroy");stopForegroundCompat(NOTIFICATION_ID); }void invokeMethod(Method method, Object[] args) {try {method.invoke(this, args);} catch (InvocationTargetException e) {// Should not happen.Log.w("ApiDemos", "Unable to invoke method", e);} catch (IllegalAccessException e) {// Should not happen.Log.w("ApiDemos", "Unable to invoke method", e);}}/*** This is a wrapper around the new startForeground method, using the older* APIs if it is not available.*/void startForegroundCompat(int id, Notification notification) {if (mReflectFlg) {// If we have the new startForeground API, then use it.if (mStartForeground != null) {mStartForegroundArgs[0] = Integer.valueOf(id);mStartForegroundArgs[1] = notification;invokeMethod(mStartForeground, mStartForegroundArgs);return;}// Fall back on the old API.mSetForegroundArgs[0] = Boolean.TRUE;invokeMethod(mSetForeground, mSetForegroundArgs);mNM.notify(id, notification);} else {/* 还可以使用以下方法,当sdk大于等于5时,调用sdk现有的方法startForeground设置前台运行,* 否则调用反射取得的sdk level 5(对应Android 2.0)以下才有的旧方法setForeground设置前台运行 */if(VERSION.SDK_INT >= 5) {startForeground(id, notification);} else {// Fall back on the old API.mSetForegroundArgs[0] = Boolean.TRUE;invokeMethod(mSetForeground, mSetForegroundArgs);mNM.notify(id, notification); }}}/*** This is a wrapper around the new stopForeground method, using the older* APIs if it is not available.*/void stopForegroundCompat(int id) {if (mReflectFlg) {// If we have the new stopForeground API, then use it.if (mStopForeground != null) {mStopForegroundArgs[0] = Boolean.TRUE;invokeMethod(mStopForeground, mStopForegroundArgs);return;}// Fall back on the old API. Note to cancel BEFORE changing the// foreground state, since we could be killed at that point.mNM.cancel(id);mSetForegroundArgs[0] = Boolean.FALSE;invokeMethod(mSetForeground, mSetForegroundArgs);} else {/* 还可以使用以下方法,当sdk大于等于5时,调用sdk现有的方法stopForeground停止前台运行,* 否则调用反射取得的sdk level 5(对应Android 2.0)以下才有的旧方法setForeground停止前台运行 */if(VERSION.SDK_INT >= 5) {stopForeground(true);} else {// Fall back on the old API. Note to cancel BEFORE changing the// foreground state, since we could be killed at that point.mNM.cancel(id);mSetForegroundArgs[0] = Boolean.FALSE;invokeMethod(mSetForeground, mSetForegroundArgs);}}}}
前台Service运行后的效果如图:
(1).通知栏显示内容:
(2).下拉后通知栏显示内容:
Android创建前台运行的Service相关推荐
- 使用startForeground让android服务前台运行
最近在使用Android 4.1系统的时候,发现在手机休眠一段时间后(1-2小时),后台运行的服务被强行kill掉,有可能是系统回收内存的一种机制,要想避免这种情况可以通过startForegroun ...
- Android Service---在前台运行服务
前台服务是哪些被认为用户知道的并且在内存低的时候不允许系统杀死的服务.前台服务必须给状态栏提供一个通知,他被放到了"正在进行中(Ongoing)"标题之下,这就意味着直到这个服务被 ...
- Android 启动后台运行程序(Service)
Android开发中,当需要创建在后台运行的程序的时候,就要使用到Service.Service 可以分为有无限生命和有限生命两种.特别需要注意的是Service跟Activities是不同的(简单来 ...
- android socket 服务,android 创建socket 通信型service
仿照instaled写的 1.声明 在system/core/rootdir/init.rc中添加: service testlang /system/bin/testlang # 名 ...
- Android开发之如何保证Service不被杀掉(前台服务)
序言 最近项目要实现这样一个效果:运行后,要有一个service始终保持在后台运行,不管用户作出什么操作,都要保证service不被kill.参考了现今各种定制版的系统和安全厂商牛虻软件,如何能保证自 ...
- 在GlassFish应用服务器上创建并运行你的第一个Restful Web Service【翻译】
前言 本人一直开发Android应用,目前Android就业形势恶劣,甚至会一路下滑,因此决定学习服务器开发.采用的语言是java,IDE是Intellij,在下载Intellij的同时看到官网很多优 ...
- android 判断activity是否在运行,Android 判断某个Activity 是否在前台运行的实例
如下所示: /** * 判断某个界面是否在前台 * * @param context Context * @param className 界面的类名 * @return 是否在前台显示 */ pub ...
- android创建标题栏,【Android】利用服务Service创建标题栏通知
创建标题栏通知的核心代码 public void CreateInform() { //定义一个PendingIntent,当用户点击通知时,跳转到某个Activity(也可以发送广播等) Inten ...
- 基于eclipse的android项目实战—博学谷(零)创建和运行Android项目
最近发现好多人出现问题,那我就加一个创建和运行项目的方法,之后的步骤就按照顺序来就行 1.首先安装jdk1.8 window系统安装JDK1.8配置详细步骤 2.安装eclipse并配置android ...
最新文章
- 茶香账簿小程序开发进度(1)
- Centos 6.5下的OPENJDK卸载和SUN的JDK安装、环境变量配置
- thymeleaf 中文_springboot 整合 thymeleaf(上手即用)
- 【STM32】程序下载(串口方式)
- DefaultServlet
- CreateCompatibleBitmap
- Java中的原生动态代理和CGLIB动态代理的原理,我不信你全知道!
- mysql 压缩备份_备份压缩mysql 数据库
- 三维重建的定位定姿算法
- 1个鼠标和1个键盘控制2台电脑(windows和linux系统)
- CentOS7 python django框架 天天生鲜项目 搭建流程
- JavaScript写入文件到本地
- 机器学习 | AHP层次分析法
- 2018年苹果年费支付失败真正的原因
- 安装linux系统提示acpi,ACPI引起linux系统无故重启
- seller_info - 获得义乌购店铺详情
- 2022全新好玩的恶搞屁声音小程序源码+UI不错
- web前端期末大作业:基于HTML+CSS+JavaScript奥迪企业bootstrap响应式网站
- Matlab sum( ) 函数
- CSS - 移动端布局(一)关键的前置知识
热门文章
- Spring Boot入门(05):了解Spring Boot的starter入门 | 超级详细,建议收藏
- 虚拟机centos7克隆
- 干货!区块链入门、进阶、行业专家观点!1000篇好文帮你破解区块链密码!(中篇)...
- 几种宽带无线接入技术的比较
- 2018 “百度之星”程序设计大赛 - 初赛(A)
- mac电脑使用小技巧
- 如何更改虚拟光驱与物理光驱的盘符
- 第五届蓝帽杯初赛:冬奥会_is_coming
- sql server存数据时报错“解索引超出了数组界限的问题”
- 部分ADSL猫的默认密码