Android创建前台运行的Service

来源:互联网 发布:数据库int括号 编辑:程序博客网 时间:2024/06/18 09:12
 

Android创建前台运行的Service

 17197人阅读 评论(1) 收藏 举报
 分类:

Service如果要防止尽可能不被系统杀掉,需要设置为在前台运行。

由于设置前台运行service的方法在2.0之前和2.0之后有所变化。

所以需要根据不同的版本进行区分;或者完全使用反射机制来处理,这样只要有相应的方法就可以使用,否则使用其他版本的方法。

下面是一个设置servcie前台运行的例子,参考了API中对Service的说明。

http://developer.android.com/reference/android/app/Service.html#

[java] view plain copy
  1. import java.lang.reflect.InvocationTargetException;  
  2. import java.lang.reflect.Method;  
  3.   
  4. import android.app.Notification;  
  5. import android.app.NotificationManager;  
  6. import android.app.PendingIntent;  
  7. import android.app.Service;  
  8. import android.content.Context;  
  9. import android.content.Intent;  
  10. import android.os.IBinder;  
  11. import android.os.Build.VERSION;  
  12. import android.util.Log;  
  13.   
  14. public class ForegroundService extends Service {  
  15.     private static final String TAG = "ForegroundService";  
  16.       
  17.     private boolean mReflectFlg = false;  
  18.       
  19.     private static final int NOTIFICATION_ID = 1// 如果id设置为0,会导致不能设置为前台service  
  20.     private static final Class<?>[] mSetForegroundSignature = new Class[] {  
  21.         boolean.class};  
  22.     private static final Class<?>[] mStartForegroundSignature = new Class[] {  
  23.         int.class, Notification.class};  
  24.     private static final Class<?>[] mStopForegroundSignature = new Class[] {  
  25.         boolean.class};  
  26.   
  27.     private NotificationManager mNM;    
  28.     private Method mSetForeground;  
  29.     private Method mStartForeground;    
  30.     private Method mStopForeground;  
  31.     private Object[] mSetForegroundArgs = new Object[1];  
  32.     private Object[] mStartForegroundArgs = new Object[2];    
  33.     private Object[] mStopForegroundArgs = new Object[1];    
  34.       
  35.     @Override    
  36.     public void onCreate() {    
  37.         super.onCreate();  
  38.         Log.d(TAG, "onCreate");  
  39.           
  40.         mNM = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);    
  41.         try {    
  42.             mStartForeground = ForegroundService.class.getMethod("startForeground", mStartForegroundSignature);    
  43.             mStopForeground = ForegroundService.class.getMethod("stopForeground", mStopForegroundSignature);    
  44.         } catch (NoSuchMethodException e) {    
  45.             mStartForeground = mStopForeground = null;    
  46.         }    
  47.           
  48.         try {  
  49.             mSetForeground = getClass().getMethod("setForeground",  
  50.                     mSetForegroundSignature);  
  51.         } catch (NoSuchMethodException e) {  
  52.             throw new IllegalStateException(  
  53.                     "OS doesn't have Service.startForeground OR Service.setForeground!");  
  54.         }  
  55.   
  56.         Notification.Builder builder = new Notification.Builder(this);  
  57.         PendingIntent contentIntent = PendingIntent.getActivity(this0,    
  58.                 new Intent(this, MainActivity.class), 0);    
  59.         builder.setContentIntent(contentIntent);  
  60.         builder.setSmallIcon(R.drawable.icon);  
  61.         builder.setTicker("Foreground Service Start");  
  62.         builder.setContentTitle("Foreground Service");  
  63.         builder.setContentText("Make this service run in the foreground.");  
  64.         Notification notification = builder.build();  
  65.           
  66.         startForegroundCompat(NOTIFICATION_ID, notification);    
  67.     }    
  68.       
  69.     @Override  
  70.     public int onStartCommand(Intent intent, int flags, int startId) {  
  71.         super.onStartCommand(intent, flags, startId);  
  72.         Log.d(TAG, "onStartCommand");  
  73.           
  74.         return START_STICKY;  
  75.     }   
  76.       
  77.     @Override    
  78.     public IBinder onBind(Intent intent) {    
  79.         return null;    
  80.     }    
  81.   
  82.     @Override    
  83.     public void onDestroy() {    
  84.         super.onDestroy();  
  85.         Log.d(TAG, "onDestroy");  
  86.           
  87.         stopForegroundCompat(NOTIFICATION_ID);    
  88.     }  
  89.       
  90.     void invokeMethod(Method method, Object[] args) {  
  91.         try {  
  92.             method.invoke(this, args);  
  93.         } catch (InvocationTargetException e) {  
  94.             // Should not happen.  
  95.             Log.w("ApiDemos""Unable to invoke method", e);  
  96.         } catch (IllegalAccessException e) {  
  97.             // Should not happen.  
  98.             Log.w("ApiDemos""Unable to invoke method", e);  
  99.         }  
  100.     }  
  101.       
  102.     /** 
  103.      * This is a wrapper around the new startForeground method, using the older 
  104.      * APIs if it is not available. 
  105.      */  
  106.     void startForegroundCompat(int id, Notification notification) {  
  107.         if (mReflectFlg) {  
  108.             // If we have the new startForeground API, then use it.  
  109.             if (mStartForeground != null) {  
  110.                 mStartForegroundArgs[0] = Integer.valueOf(id);  
  111.                 mStartForegroundArgs[1] = notification;  
  112.                 invokeMethod(mStartForeground, mStartForegroundArgs);  
  113.                 return;  
  114.             }  
  115.       
  116.             // Fall back on the old API.  
  117.             mSetForegroundArgs[0] = Boolean.TRUE;  
  118.             invokeMethod(mSetForeground, mSetForegroundArgs);  
  119.             mNM.notify(id, notification);  
  120.         } else {  
  121.             /* 还可以使用以下方法,当sdk大于等于5时,调用sdk现有的方法startForeground设置前台运行, 
  122.              * 否则调用反射取得的sdk level 5(对应Android 2.0)以下才有的旧方法setForeground设置前台运行 */  
  123.               
  124.             if(VERSION.SDK_INT >= 5) {  
  125.                 startForeground(id, notification);  
  126.             } else {  
  127.                 // Fall back on the old API.  
  128.                 mSetForegroundArgs[0] = Boolean.TRUE;  
  129.                 invokeMethod(mSetForeground, mSetForegroundArgs);  
  130.                 mNM.notify(id, notification);      
  131.             }  
  132.         }  
  133.     }  
  134.   
  135.     /** 
  136.      * This is a wrapper around the new stopForeground method, using the older 
  137.      * APIs if it is not available. 
  138.      */  
  139.     void stopForegroundCompat(int id) {  
  140.         if (mReflectFlg) {  
  141.             // If we have the new stopForeground API, then use it.  
  142.             if (mStopForeground != null) {  
  143.                 mStopForegroundArgs[0] = Boolean.TRUE;  
  144.                 invokeMethod(mStopForeground, mStopForegroundArgs);  
  145.                 return;  
  146.             }  
  147.       
  148.             // Fall back on the old API.  Note to cancel BEFORE changing the  
  149.             // foreground state, since we could be killed at that point.  
  150.             mNM.cancel(id);  
  151.             mSetForegroundArgs[0] = Boolean.FALSE;  
  152.             invokeMethod(mSetForeground, mSetForegroundArgs);  
  153.         } else {  
  154.             /* 还可以使用以下方法,当sdk大于等于5时,调用sdk现有的方法stopForeground停止前台运行, 
  155.              * 否则调用反射取得的sdk level 5(对应Android 2.0)以下才有的旧方法setForeground停止前台运行 */  
  156.               
  157.             if(VERSION.SDK_INT >= 5) {  
  158.                 stopForeground(true);  
  159.             } else {  
  160.                 // Fall back on the old API.  Note to cancel BEFORE changing the  
  161.                 // foreground state, since we could be killed at that point.  
  162.                 mNM.cancel(id);  
  163.                 mSetForegroundArgs[0] = Boolean.FALSE;  
  164.                 invokeMethod(mSetForeground, mSetForegroundArgs);  
  165.             }  
  166.         }  
  167.     }  
  168.   
  169. }  

前台Service运行后的效果如图:

(1).通知栏显示内容:


(2).下拉后通知栏显示内容:


4
0 0
原创粉丝点击