Service如果要防止尽可能不被系统杀掉,需要设置为在前台运行。
由于设置前台运行service的方法在2.0之前和2.0之后有所变化。
所以需要根据不同的版本进行区分;或者完全使用反射机制来处理,这样只要有相应的方法就可以使用,否则使用其他版本的方法。
下面是一个设置servcie前台运行的例子,参考了API中对Service的说明。
http://developer.android.com/reference/android/app/Service.html#
[java] view
plaincopy
- 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);
- }
- }
- }
- }
Demo:http://download.csdn.net/detail/u012808234/9367032
时间: 2024-12-02 22:21:10