Android建立前台啟動並執行Service

來源:互聯網
上載者:User

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);            }        }    }}

前台Service運行後的效果

(1).通知欄顯示內容:

(2).下拉後通知欄顯示內容:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.