首页 > 解决方案 > 如何安排任务以便它在android中的任何条件下执行

问题描述

我正在开发一个需要在某些时候运行一些任务的 Android 项目。用户选择要执行的任务以及需要执行的时间。我曾尝试使用 BroadcastReceiverAlarmManager在当时执行任务。但问题是 -当应用程序关闭时任务停止执行。下面是我的代码BroadcastReceiverAlarmManager类。

public class AlarmReceiver extends BroadcastReceiver {

    private static final String TAG = "AlarmReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: Alarm received");

        // perform the task here using the values received by Intent
    }
}

AlarmReceiver我称之为AlarmManager

    Intent alarmIntent = new Intent(this, AlarmReceiver.class);
    alarmIntent.putExtra("foo", foo);
    alarmIntent.putExtra("bar", bar);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, date.getTime(), pendingIntent);

date.getTime()执行任务的时间在哪里。

一切正常。但我想要一个解决方案,即使应用程序被强制关闭,它也能正常工作。 我还希望解决方案能够执行一个接一个甚至第二天安排的多个此类任务。如果可能的话

注意:我想用一个Service类来完成这个,但不知道如何编写这个Service类。

标签: javaandroidservice

解决方案


我认为强制关闭不会让任务继续工作。但是,您可以在系统事件上注册一个 BroadcastReceiver 以让应用程序恢复运行(例如 android.intent.action.BOOT_COMPLETED 和 QUICKBOOT_POWERON)

对于任务,您应该真正查看 WorkManager 库。

请参阅:https ://developer.android.com/reference/androidx/work/package-summary和https://developer.android.com/topic/libraries/architecture/workmanager 它为你做了很多工作来听系统事件。它为重复性和单一任务提供了 PeriodicWorkRequest 和 OneTimeWorkRequest。

最新库:androidx.work:work-runtime:2.2.0

import androidx.work.Constraints
import androidx.work.ExistingPeriodicWorkPolicy.REPLACE
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager

    private fun startTask(interval: Int) {
        val flexInterval = when {
            interval > 200 -> 30L
            interval > 59 -> 15L
            else -> 5L
        }
        val constraints = Constraints.Builder().setRequiresBatteryNotLow(true).build()

        val fileFinderWork = PeriodicWorkRequest.Builder(
            FileFindWorker::class.java,
            interval.toLong(), TimeUnit.MINUTES,
            flexInterval, TimeUnit.MINUTES
        ).setConstraints(constraints).addTag(WORK_TAG).build()

        Logger.e("Enqueueing file finder worker ($interval min.)")

        val manager: WorkManager = WorkManager.getInstance(ctx)
        manager.enqueueUniquePeriodicWork(WORK_NAME, REPLACE, fileFinderWork)
   }

或者在 Java 中

import androidx.work.Constraints;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;

    private UUID startTask() {
        int interval = 99 /* Just a value from configuration */;
        TimeUnit unit;
        int flexInterval;

        if (interval % 60 == 0) {
            interval = interval / 60;
            unit = TimeUnit.HOURS;
        } else {
            unit = TimeUnit.MINUTES;
        }

        if (interval >= 240) {
            flexInterval = 30;
        } else if (interval >= 60) {
            flexInterval = 15;
        } else {
            flexInterval = 5;
        }

        final Constraints constraints = new Constraints.Builder()
                .setRequiresBatteryNotLow(true)
                .build();

        final PeriodicWorkRequest fileFinderWork = new PeriodicWorkRequest.Builder(
                FileFindWorker.class, interval, unit, flexInterval, TimeUnit.MINUTES)
                .setConstraints(constraints)
                .addTag(WORK_TAG)
                .build();

        lastPeriodicUuid = fileFinderWork.getId();

        WorkManager manager = WorkManager.getInstance(ctx)
        manager.enqueueUniquePeriodicWork(WORK_NAME, ExistingPeriodicWorkPolicy.REPLACE, fileFinderWork);

        return fileFinderWork.getId();
    }


推荐阅读