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

How to create a job with WorkManager when device is plugged in?

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

这是工作人员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 的模式,我可以给你一个想法,这取决于人们倾向于为他们的 phone 收费的事实每次都超过几分钟。

您可以组合使用 2 种 WorkRequests

  • OneTimeWorkRequest 这就是你算法的实际逻辑。 将约束设置为仅在充电时。
    一旦触发,该工作人员将无任何限制地入队 PeriodicWorkRequest"The minimum repeat interval that can be defined is 15 minutes"

  • PeriodicWorkRequest 每 15 分钟触发一次并定期检查 phone 是否仍在充电。
    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:

首先,用tag构建它:

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

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

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

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

然后用WorkManager.getInstance().cancelUniqueWork(workName)

取消

你应该使用 PeriodicWorkRequest 让你的工作经理在你选择 Fays Minutes Hours 的时间工作很多时间