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 ...
最新文章
- [NC16591]关押罪犯 并查集
- 电信、联通、移动、其它路由表 2011-06-19更新
- 网站优化之交换友情链接应注意什么?
- iOS 仿看了吗应用、指南针测网速等常用工具、自定义弹出视图框架、图片裁剪、内容扩展等源码...
- iOS 模糊化效果 ANBlurredImageView的使用
- SpringBoot中操作spring redis的工具类
- 初始Angularjs2
- vue2.0 keep-alive最佳实践
- 提交日期表单状态操作_奇怪的知识又增加了,表单还能查寝?
- 怎么把图片上的字去掉_视频片头怎么减掉,电脑如何剪切掉视频的开头「视频批量剪辑」...
- echarts x轴加箭头,ECharts X轴(xAxis)
- Scala Singleton对象
- 我的世界服务器怎么修改标语,怎么用资源包修改我的世界闪烁标语
- Newtonsoft.Json基础问题
- Vmware安装深度Deepin图文
- Illumination Normalization Based on Weber’s Law With Application to Face Recognition
- 在GIS中UTM和WGS84的区别
- HTML之部分易忘点
- html复习第四课(2_34_0924_html)
- 域权限维持——黄金票据和白金票据