防止服务被破坏

时间:2018-07-02 11:36:08

标签: android service

我有必要启动一个永久服务,该服务每x小时执行一些任务。我已经通过以下方式实现了它: MainActivity

 Intent intent = new Intent(getApplicationContext(), BootReceiver.class);
    PendingIntent pintent = PendingIntent.getBroadcast(this, 1, intent, 0);
    AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    if (alarm != null) {
        alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pintent);
    }

服务:

public class MyService extends Service {


@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();
    Log.d("Testing", "Service got created");
    Toast.makeText(this, "MyService.onCreate()", Toast.LENGTH_LONG).show();
}

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    Log.d("Testing", "Service got destroyed");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Auto-generated method stub
    super.onStartCommand(intent, flags, startId);
    Toast.makeText(this, "MyService.onStart()", Toast.LENGTH_LONG).show();
    Log.d("Testing", "Service got started");


    new AsyncNotify().execute(this);


    return START_STICKY;
}

@Override
public void onTaskRemoved(Intent rootIntent) {
    super.onTaskRemoved(rootIntent);
    Log.d("Testing", "Service got task removed");

    Log.d("Testing", "TASK REMOVED");

    PendingIntent service = PendingIntent.getService(
            getApplicationContext(),
            1001,
            new Intent(getApplicationContext(), MyService.class),
            PendingIntent.FLAG_ONE_SHOT);

    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 5000, service);
}

}

广播接收器:

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

        Intent i = new Intent(context, MyService.class);
        PendingIntent pintent = PendingIntent.getService(context, 0, i, 0);
        AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        if (alarm != null) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, 60000,
                    pintent);
        }

}

}

问题是,当我关闭应用程序时,广播接收器继续处于活动状态,但是服务输入为OnDestroyed,因此广播接收器无法调用服务。

编辑尝试使用WorkManager。

主要活动:

WorkManager wm = WorkManager.getInstance();

    PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(MyWorker.class, 60,
            TimeUnit.SECONDS)
            .build();

    if (wm != null) {
        wm.enqueue(periodicWork);
    }

工人:

public class MyWorker extends Worker {

public MyWorker() {}

@NonNull
@Override
public Result doWork() {
    Log.d("Testing", "OK");
    return Result.SUCCESS;
}

}

现在的问题是,工作只在第一次执行,然后什么也没有执行。

2 个答案:

答案 0 :(得分:0)

从Android 8.0开始,不允许服务在后台持久运行,这也包括AlarmManager回调。

检查一次this迁移文档。

解决方案:对于面向android 26及更高版本的应用,建议使用WorkManager link进行后台任务。

在您遇到问题的情况下,您可能可以使用PeriodicWorkRequest,它的作用就像是一个超级按钮!

答案 1 :(得分:0)

请参阅此PeriodicWorkRequest GitHub demo,该日期每天在维护时段(每24小时)更新一次天数计数器。无论应用程序是打开还是关闭,它都会执行doWork()方法。

WorkManager版本 1.0.0-alpha04 是最近推出的,并且仍处于alpha模式,因此一旦它们发布了最终版本,它将对所有设备完全起作用。