您的位置:首页 > 移动开发 > Android开发

Android创建前台运行的Service

2016-11-29 10:21 288 查看
 


Android创建前台运行的Service

2013-06-22 14:44 17197人阅读 评论(1) 收藏 举报


 分类:

Android应用(105) 


版权声明:本文为博主原创文章,未经博主允许不得转载。

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

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

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

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

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

[java] view
plain copy

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).下拉后通知栏显示内容:





顶4
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息