转自http://blog.csdn.net/ameyume/article/details/9150755
版权声明:本文为博主原创文章,未经博主允许不得转载。
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,会导致不能设置为前台service
- private 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);
- }
- @Override
- public 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);
- }
- }
- }
- }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148import 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,会导致不能设置为前台service private 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); } @Override public 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的全部内容,更多相关Android创建前台运行内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复