定期工作经理在未充电或屏幕关闭时未在android pie上显示通知
我有一个应用程序,应该显示通知每2小时,并应停止,如果用户已经采取行动的notif。由于后台服务现在已经成为历史,因此我考虑使用WorkManager(定期工作经理在未充电或屏幕关闭时未在android pie上显示通知,android,android-workmanager,xiaomi,Android,Android Workmanager,Xiaomi,我有一个应用程序,应该显示通知每2小时,并应停止,如果用户已经采取行动的notif。由于后台服务现在已经成为历史,因此我考虑使用WorkManager(“android.arch.work:work-runtime:1.0.0-beta01”)实现同样的功能 我的问题是,虽然work manager在应用程序运行时成功地显示了通知,但在以下情况下它不会一致地显示通知(我将检查一致性的时间跨度从2小时缩短为2分钟): 当应用程序从后台被删除时 设备处于屏幕关闭状态 状态设备处于未连接状态(即未充
“android.arch.work:work-runtime:1.0.0-beta01”
)实现同样的功能
我的问题是,虽然work manager在应用程序运行时成功地显示了通知,但在以下情况下它不会一致地显示通知(我将检查一致性的时间跨度从2小时缩短为2分钟):
- 当应用程序从后台被删除时
- 设备处于屏幕关闭状态
- 状态设备处于未连接状态(即未充电)
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);
}
....
}
这是worker类(我可以发布showNotif(…)
和setNotificationChannel(…)
,如果它们可能出错的话):
我使用的是一款小米miA2安卓手机和安卓派(SDK 28)。还有其他一些事情困扰着我:
- 我能做些什么来知道我的WorkManager是否正在运行?另一种是等待2个小时,希望得到通知。实际上,我试过类似的方法,让我的手机与pc保持连接,并时不时地检查android studio的logcat。它确实会在实际调用worker时运行所有日志,但我认为这不是测试它的正确方法,或者是吗
- 在上面的代码中,每次打开应用程序时,都会从
onCreate()
调用setDailNotifier()。是不是错了?每个
是否应该有一些唯一的id,以及像WorkRequest
这样的检查函数,它可以让我们检查一个工人是否已经在给定的任务中??如果这是WorkManger.isRequestRunning(request.getID)
的情况,那么我们就会一团糟李>AsyncTask
WorkManager的最小周期间隔为15分钟,不保证在精确的时间执行任务。您可以在上阅读更多关于此的信息 当您使用WorkManager计划任务时,您在较新的Android版本上的所有常规后台限制仍然是相关的。WorkManager保证即使应用程序被终止或设备被重述,任务也会被执行,但它不能保证任务的准确执行 有一个注意事项是,当你的应用程序被终止时,任务将被重新安排。一些OEM对操作系统和Launcher应用程序进行了修改,使WorkManager无法完成这些功能 : 是的,即使手机是中国手机也是如此。
我们遇到的唯一一个问题是,一些中国原始设备制造商将最近的swipe解雇视为强制停止。当这种情况发生时,WorkManager将在下次应用程序启动时重新安排所有挂起的作业。考虑到这是一个CDD冲突,WorkManager在拥有一个客户机库的情况下所能做的就不多了 此外,如果设备制造商决定修改库存Android以强制停止应用程序,WorkManager将停止工作(JobScheduler、警报、广播接收器等也将停止工作)。没有办法解决这个问题。不幸的是,一些设备制造商会这样做,因此在这种情况下,WorkManager将停止工作,直到下一次应用程序启动
到目前为止,我已经安装了这个应用程序8天了,我可以确认代码是正确的,并且应用程序工作正常。如所述,工作经理安排工作的最小时间间隔为15分钟,因此
WorkManager
在我的测试条件下按预期工作的可能性较小(2分钟)。以下是我的一些其他观察结果:
- 正如我在问题中所说的,我在4小时内无法收到通知,即使我已经超过了重复间隔2小时。这是因为。我通过了15分钟的弹性时间,现在它显示了正确时间间隔之间的通知。因此,我将标记pfmaggi的答案为正确李>
- 重复工作请求的问题可以通过将
替换为WorkManager.getInstance().enqueue(request)
- 我仍然无法找到一种方法以我描述的方式测试工作经理
WorkManager的最小周期间隔为15分钟,并且不保证在精确的时间执行任务
因此,有什么方法可以测试此类模块?你能解释一下这个15分钟的最小周期间隔吗?比如,如果用户必须制作一个聊天应用程序,每2分钟从服务器上检查一条收到的消息,该怎么办?对于示例应用程序,最好的选择是从服务器上推送通知,而不是每x分钟轮询一次新消息。这对设备的电池来说要好得多。我在安卓pie OnePlus手机上每15分钟测试一次,但我注意到现在已经超过20分钟了,但在第一次有人知道如何让Perioodc管理器工作后,通知就没有显示出来
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();
}