我想创建一个在设备插入时触发的作业,就像 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 .
如果你真的想使用这种 WorkManger
和 Requests
的模式,我可以给你一个想法,这取决于人们倾向于为手机充电的事实每次都超过几分钟。
您可以结合使用 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/