android - 插入设备时如何使用 WorkManager 创建作业?

标签 android android-workmanager

我想创建一个在设备插入时触发的作业,就像 ACTION_POWER_CONNECTED 的广播接收器一样。

这是 worker 类(Class):

public class ChargerWorker extends Worker {

/* Constants */
    private static final String TAG = "ChargerWorker";
    private static final long TRIGGER_AGE = TimeUnit.MINUTES.toMillis(30);       // At least 30 min old.

    @NonNull
    @Override
    public Result doWork() {
        Log.e(TAG, "Power connection worker of Indoor/Outdoor lib.");
        IndoorOutdoorLogger.v(TAG, "Power connection worker of Indoor/Outdoor lib.");
        Context context = getApplicationContext();

        if (Conditions.isBatteryChargingOnAC(context)) {
            IndoorOutdoorLogger.d(context, TAG, "Power plugged and connected to AC.");
            Log.e(TAG, "Power plugged and connected to AC.");

            if (WiFiConnection.isWifiConnected(context) && WiFiConnection.isCurrentNetworkIndoorRecognized(context)) {
                // In this case an "upgrade" to the confidence level is possible.
                // Only run when the last known detection is old enough.
                DetectionResult latestResult = DetectionResult.loadFromCache(context);
                if (!latestResult.isTimestampValid(TRIGGER_AGE)) {
                    IndoorOutdoorLogger.d(context, TAG, "AC power while connected to a recognized WiFi network, and last detection is old enough, starting detection.");
                    IndoorOutdoorClient client = new IndoorOutdoorClient(context, null);
                    client.startShortDetection(Trigger.POWER);
                }
            }
        }
        return Result.SUCCESS;
    } }

这是我在 onCreate() 方法中初始化工作的方式:

Constraints constraints = new Constraints.Builder().setRequiresCharging(true).build();
        OneTimeWorkRequest simpleReuquest = new OneTimeWorkRequest.Builder(ChargerWorker.class)
                .setConstraints(constraints)
                .build();
        WorkManager.getInstance().enqueue(simpleReuquest);

当我第一次将设备连接到适配器时,一切正常。但是,当我断开设备并重试时,我再也没有达到 doWork 功能。 相反,我在 logcat 中看到以下消息:

E/WorkerWrapper: Status for 031e39f1-bc10-4a35-9341-11453fc0ca21 is SUCCEEDED; not doing any work.

是因为我使用了OneTimeWorkRequest吗?如果是这样,我如何安排它在每次设备连接到电源时运行?

最佳答案

因为你使用了OnTimeWorkRequest,从它的名字你可以推断出这个请求只有一次有效。一旦被触发,它就不会被再次调用,除非你再次对它进行排队。
问题是 WorkManager 不支持与您的需求相关的任何其他请求或约束。看看this question .

如果你真的想使用这种 WorkMangerRequests 的模式,我可以给你一个想法,这取决于人们倾向于为手机充电的事实每次都超过几分钟。

您可以结合使用 2 种类型的 WorkRequests:

  • OneTimeWorkRequest 这是您算法的实际逻辑。 将约束设置为仅在充电时。
    一旦触发,该工作人员将在没有任何约束的情况下将 PeriodicWorkRequest 加入队列,并且 "The minimum repeat interval that can be defined is 15 minutes"

  • PeriodicWorkRequest 每 15 分钟触发一次,并定期检查手机是否仍在充电。
    worker 第一次检测到设备被拔掉时,它会将上面的 OneTimeWorkRequest 排入队列并自行取消。

这样你就不会检测到设备电源状态的快速变化,但它是自 apps that target the API level 26 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest 以来 Android Oreo(及更高版本)中最好的可能。

检查您的设备是否已插入:

你甚至可以检测它是哪种充电,使用这个代码:

IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);

// Are we charging / charged?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                 status == BatteryManager.BATTERY_STATUS_FULL;

// How are we charging?
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;

taken right from android developer guide

取消WorkRequest:

首先,使用标签构建它:

OneTimeWorkRequest.Builder(MyWorker.class)
            .setConstraints(myConstraints)
            .addTag(tag)
            .build();

然后执行 WorkManager.getInstance().cancelAllWorkByTag(tag)

另一种选择是将一个独特的作品加入队列:

WorkManager.getInstance().enqueueUniquePeriodicWork(
            uniqueWorkName, ExistingPeriodicWorkPolicy.REPLACE, periodicWork);

然后使用 WorkManager.getInstance().cancelUniqueWork(workName) 取消它

关于android - 插入设备时如何使用 WorkManager 创建作业?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55335853/

相关文章:

android - 如何为 worker 类实现 Dagger?

android - 自定义 View 寻呼机 :Error inflating class android. support.v4.app.ViewPager

Android Studio 0.5.0 - 升级后没有自动代码完成和错误语法识别器

android - 运行 Android 模拟器 : "Warning: data partition already in use" 的问题

android - TooltipCompat 崩溃但我没有在我的代码中使用任何地方

android - 如何创建 WorkerParameters

android - 截击传递数组作为参数

android - Amazon S3 TransferUtility 在应用程序关闭时停止,即使在 WorkManager 中也是如此

android - WorkManager 在尝试将唯一的周期性工作排入 Application#onCreate 时崩溃

java - WorkManager 中的 Worker 和 ListenableWorker 有什么区别?