Android 防止服务被破坏

Android 防止服务被破坏,android,service,Android,Service,我有必要启动一个永久服务,每x小时执行一次任务。我以以下方式实现了它: 主要活动 Intent intent = new Intent(getApplicationContext(), BootReceiver.class); PendingIntent pintent = PendingIntent.getBroadcast(this, 1, intent, 0); AlarmManager alarm = (AlarmManager)getSystemService(Con

我有必要启动一个永久服务,每x小时执行一次任务。我以以下方式实现了它: 主要活动

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

}
}

问题是,当我关闭应用程序时,broadcastreceiver继续处于活动状态,但服务进入OnDestroyed,因此broadcastreceiver无法调用该服务

编辑并尝试使用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;
}
}


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

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

检查迁移文档一次

解决方案:对于针对android 26及以上版本的应用程序,建议在后台任务中使用
WorkManager

在您的问题上下文中,您可能可以使用
PeriodicWorkRequest
,它就像一个符咒

在维护窗口期间,每天(每24小时)更新一次日计数器。无论应用程序是打开还是关闭,它都执行doWork()方法


WorkManager版本1.0.0-alpha04最近推出,但仍处于alpha模式,因此在最终版本发布后,它将完全适用于所有设备。

使用jobscheduler/WorkManager或类似于计划周期性任务。不要试图使服务永远保持活动状态。这是不可行的,对电池不友好是的,我用这个解决方案编辑过,但这项工作只是第一次执行。我不知道你是如何测试的。最小间隔可能高于您的测试间隔mm是的,可能是。有没有办法快速测试它?还是每次考试我都要等一个小时Dit可能有文档记录。检查开发人员站点我已经尝试过PeriodicWorkRequest,但问题是只执行第一个workrequest,然后不执行任何操作。你确定吗?JobScheduler在给定的每个周期时间内部调用它。workmanager是它的包装器,因此它应该可以工作。PeriodicWorkRequest periodicWork=new PeriodicWorkRequest.Builder(MyWorker.class,60,TimeUnit.SECONDS)。build();-PeriodicWorkRequest要求至少15分钟的间隔。给定的间隔将设置为默认的最小周期间隔。参考: