我有一个应用程序应该每 2 小时显示一次通知,如果用户已经对通知采取了行动,应该停止。由于后台服务现在已经成为历史,我想使用 WorkManager ( "android.arch.work:work-runtime:1.0.0-beta01"
) 来做同样的事情。
我的问题是,虽然工作经理在应用程序运行时成功显示了通知,但在以下情况下它不会一致地显示通知(我将时间跨度从 2 小时减少到 2 分钟以检查一致性):
- 当应用程序从后台被杀死时。
- 设备处于屏幕关闭状态。
- 状态设备处于拔出状态(即未充电)。
通过一致性,我的意思是通知在给定的时间跨度内至少显示一次。在 2 分钟的时间跨度内,通知的频率从每 4 分钟一次变为完全不显示任何通知。2 小时时间跨度(我真正想要的时间跨度),已经 4 小时,我没有收到任何通知。这是我用来调用 WorkManger 的代码:
public class CurrentStreakActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
setDailyNotifier();
...
}
private void setDailyNotifier() {
Constraints.Builder constraintsBuilder = new Constraints.Builder();
constraintsBuilder.setRequiresBatteryNotLow(false);
constraintsBuilder.setRequiredNetworkType(NetworkType.NOT_REQUIRED);
constraintsBuilder.setRequiresCharging(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
constraintsBuilder.setRequiresDeviceIdle(false);
}
Constraints constraints =constraintsBuilder.build();
PeriodicWorkRequest.Builder builder = new PeriodicWorkRequest
.Builder(PeriodicNotifyWorker.class, 2, TimeUnit.HOURS);
builder.setConstraints(constraints);
WorkRequest request = builder.build();
WorkManager.getInstance().enqueue(request);
}
....
}
这是工人阶级( 如果他们可能是错误 的showNotif(..)
,我也可以发布):setNotificationChannel(...)
public class PeriodicNotifyWorker extends Worker {
private static final String TAG = "PeriodicNotifyWorker";
public PeriodicNotifyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
Log.e(TAG, "PeriodicNotifyWorker: constructor called" );
}
@NonNull
@Override
public Result doWork() {
// Log.e(TAG, "doWork: called" );
SharedPreferences sp =
getApplicationContext().getSharedPreferences(Statics.SP_FILENAME, Context.MODE_PRIVATE);
String lastcheckin = sp.getString(Statics.LAST_CHECKIN_DATE_str, Statics.getToday());
// Log.e(TAG, "doWork: checking shared preferences for last checkin:"+lastcheckin );
if (Statics.compareDateStrings(lastcheckin, Statics.getToday()) == -1) {
Log.e(TAG, "doWork: last checkin is smaller than today's date, so calling creating notification" );
return createNotificationWithButtons(sp);
}
else {
Log.e(TAG, "doWork: last checkin is bigger than today's date, so no need for notif" );
return Result.success();
}
}
private Result createNotificationWithButtons(SharedPreferences sp) {
NotificationManager manager =
(NotificationManager) getApplicationContext().getSystemService((NOTIFICATION_SERVICE));
String channel_ID = "100DaysOfCode_ID";
if (manager != null) {
setNotificationChannel(manager,channel_ID);
showNotif(manager, channel_ID, sp);
return Result.success();
}
else {
return Result.failure();
}
我正在使用带有 Android Pie(SDK 28)的小米 miA2 androidOne 设备。还有一些其他的事情让我感到困扰:
- 我可以做些什么来知道我的 WorkManager 是否正在运行?其他只需等待 2 小时并希望收到通知。我实际上尝试过类似的方法,让我的手机连接到电脑并不时检查 android studio 的 logcat。它确实在实际调用工作人员时运行所有日志,但我认为这不是测试它的正确方法,或者是吗?
- 在上面的代码中,每次打开应用程序时都会
setDailyNotifier()
调用。onCreate()
是不是错了?不应该有一些唯一的 idWorkRequest
和一个检查函数,比如WorkManger.isRequestRunning(request.getID)
它可以让我们检查一个工人是否已经在给定的任务上?如果这是一个例子AsyncTask
,那么男孩我们会一团糟。
我还在这里检查了@commonsware 关于屏幕关闭时唤醒锁的回答,但我记得工作经理确实在可用时在内部使用警报管理器。那么我在这里错过了什么?