使用START_STICKY进行服务

时间:2016-06-16 12:26:51

标签: android android-service android-service-binding

我想创建服务,即使主应用已关闭,也会每隔一段时间检查一次新通知。

添加到清单

    <service
        android:name=".service.NotificationService"
        android:enabled="true"
        android:exported="true"
        android:stopWithTask="false"
        android:process=":notification"/>

    <!-- Declaring broadcast receiver for BOOT_COMPLETED event. -->
    <receiver android:name=".BootReceiver"
        android:enabled="true"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
        >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.DEFAULT" />

        </intent-filter>
    </receiver>

其次是启动接收器,它也将在重启后启动服务。

NotificationService.class

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.IBinder;
import android.util.Log;

import com.tagwishes.fc.Notification;
import com.tagwishes.fc.app.AppConfig;
import com.tagwishes.fc.helper.SessionManager;

import java.util.Timer;
import java.util.TimerTask;

public class NotificationService extends Service {


    static int WIFI_NETWORK_ID = 1;
    static int MOBILE_NETWORK_ID = 2;
    static int NO_NETWORK_ID = 3;
    private SessionManager sm;


    final String LOG_TAG = "fc";

    public void onCreate() {
        super.onCreate();
        Log.d(LOG_TAG, "MyService onCreate");
    }

    public void onDestroy() {
        super.onDestroy();
        Log.d(LOG_TAG, "MyService onDestroy");
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(LOG_TAG, "MyService onStartCommand");


        readFlags(flags);
        MyRun mr = new MyRun(startId);
        new Thread(mr).start();


        Log.d("fc", "START_STICKY");

        return START_STICKY;
    }

    public IBinder onBind(Intent arg0) {
        return null;
    }

    int chkStatus() {
        final ConnectivityManager connMgr = (ConnectivityManager)
                this.getSystemService(Context.CONNECTIVITY_SERVICE);
        final android.net.NetworkInfo wifi = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        final android.net.NetworkInfo mobile = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        if (wifi.isConnectedOrConnecting()) {
            return WIFI_NETWORK_ID;
        } else if (mobile.isConnectedOrConnecting()) {
            return MOBILE_NETWORK_ID;
        } else {
            return NO_NETWORK_ID;
        }
    }

    void readFlags(int flags) {
        if ((flags&START_FLAG_REDELIVERY) == START_FLAG_REDELIVERY)
            Log.d(LOG_TAG, "START_FLAG_REDELIVERY");
        if ((flags&START_FLAG_RETRY) == START_FLAG_RETRY)
            Log.d(LOG_TAG, "START_FLAG_RETRY");
    }

    class MyRun implements Runnable {

        int startId;

        public MyRun(int startId) {
            this.startId = startId;
            Log.d(LOG_TAG, "MyRun#" + startId + " create");
        }

        public void run() {
            Log.d(LOG_TAG, "MyRun#" + startId + " start");

            final int networkID = chkStatus();

            Log.d("fc", "networkID " + networkID);

            if (sm == null) {
                sm = new SessionManager(getApplication());
            }

            int reCheckTime = AppConfig.NOTIFICATION_RECHECK_DEFAULT;

            if (networkID == WIFI_NETWORK_ID) {
                reCheckTime = AppConfig.NOTIFICATION_RECHECK_WIFI;
            } else if (networkID == MOBILE_NETWORK_ID) {
                reCheckTime = AppConfig.NOTIFICATION_RECHECK_MOBILE;
            }


            final Notification nt = new Notification(getApplicationContext());//Its my own class


            Log.d("fc", "Timer check noti started " + reCheckTime);
            new Timer().scheduleAtFixedRate(new TimerTask(){
                @Override
                public void run(){

                    if (networkID != NO_NETWORK_ID || !sm.isLoggedIn()) {//IF HAVE NETWORK CONNECTION
                        Log.d("fc", "checkNotifications ");

                        nt.checkNotifications();
                    }

                }
            }, 0, reCheckTime*1000);


        }

    }

}

启动接收器

public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

    Log.d("fc", "BootReceiver BroadcastReceiver");

    Intent myIntent = new Intent(context, NotificationService.class);
    context.startService(myIntent);
}

}

这就是我如何在MainActivity上调用服务

        Intent bindIntent = new Intent(getBaseContext(), NotificationService.class);
        startService(bindIntent);

当我从应用程序历史记录中关闭应用程序时,它也会关闭我的:通知进程,并且服务无法再次启动。我使用START_STICKY。

2 个答案:

答案 0 :(得分:0)

onDestroy功能

中启动您的服务
@Override
protected void onDestroy() {
super.onDestroy();
//startService()
}

答案 1 :(得分:0)

对于nadroid O +,您必须致电startForground服务。所以这将是您的接收者:

 public void onReceive(Context context, Intent intent) {

   
    Intent service = new Intent(context, NotificationService.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(service);
    } else {
        context.startService(service);
    }

当然还要在清单中声明前台服务。