我想创建一个插入设备后将触发的作业,就像ACTION_POWER_CONNECTED
的广播接收器一样。
这是工人阶级:
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
吗?如果是这样,我如何安排它在设备每次连接电源时运行?
答案 0 :(得分:1)
此是,因为您使用OnTimeWorkRequest
,因此可以从其名称推断该请求仅有效一次。一旦触发,它将不会被再次调用,除非您再次对其进行排队。
问题是WorkManager
不支持与您的需求相关的任何其他请求或约束。看看this question。
如果您真的想使用WorkManger
和Requests
的这种模式,我可以给您一个想法,这是基于人们每次都为手机充电超过几分钟的事实。
您可以结合使用两种类型的WorkRequests
:
OneTimeWorkRequest
是算法的实际逻辑。
将约束设置为仅在充电时。
触发后,此工作人员将进入PeriodicWorkRequest
,不受任何约束,"The minimum repeat interval that can be defined is 15 minutes"
PeriodicWorkRequest
,它将每15分钟触发一次,并定期检查手机是否仍在充电。
工作人员首次检测到设备已拔出电源时,会从上方进入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)
答案 1 :(得分:0)
您应该使用PeriodicWorkRequest来让您的工作经理按您选择的“ Fays Minutes Hours”中的时间进行多次工作