java - 根据特定日期安排定期本地通知
问题描述
我想让一个定期工作人员根据客户收集日期的总数安排通知。我已经分开了,但我面临一个问题。
目标:
检查是否有明天取货日期的客户,然后安排在明天上午 10 点显示通知以提醒用户,并每天重复同样的事情。
我所做的工作:
首先,我基于定期工作管理器开发了这个解决方案。
CollectionNotificationWorker.java:
public class CollectionNotificationWorker extends Worker {
public static final String WORKER_TAG = "COLLECTION_NOTIFICATION_WORKER_TAG";
private final Context context;
public CollectionNotificationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context;
}
@NonNull
@Override
public Result doWork() {
checkTomorrowsCollection(
//tomorrow's date
);
return Result.success();
}
private void checkTomorrowsCollection(String date) {
DbOperationCaller.read(AppDatabase.getAppDatabase().getCustomerDao()
.countCollectionByDate("%" + date + "%"),
new GenericOnceTimeReadingDbOperationObserver<Integer>() {
@Override
public void onSuccess(@NotNull Integer customersWithCollectionDate) {
if (customersWithCollectionDate > 0) {
setAlarm();
}
}
}
);
}
private void setAlarm() {
AlarmManager am = (AlarmManager) SharedLibrary.getApplicationContext()
.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), AlarmBroadcast.class);
PendingIntent pendingIntent =
PendingIntent.getBroadcast(
context,
ALARM_REQUEST_CODE,
intent,
PendingIntent.FLAG_ONE_SHOT);
am.set(AlarmManager.RTC_WAKEUP,
//tomorrow's date , pendingIntent);
}
警报广播.java:
public class AlarmBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
DbOperationCaller.read(AppDatabase.getAppDatabase().getCustomerDao()
.countCollectionByDate(
"%" + convertToString(getCurrentCalendar().getTime()) + "%"
),
new GenericOnceTimeReadingDbOperationObserver<Integer>() {
@Override
public void onSuccess(@NotNull Integer customersWithCollectionDate) {
if (customersWithCollectionDate > 0) {
setupNotification(context, customersWithCollectionDate);
}
}
}
);
}
private void setupNotification(Context context, int customersWithCollectionDate) {
// setup Notification here ...
}
}
MainActivity.java:
PeriodicWorkRequest collectionCheckerWorkRequest = new PeriodicWorkRequest
.Builder(CollectionNotificationWorker.class, 15, TimeUnit.MINUTES)
.build();
WorkManager.getInstance(this)
.enqueue(collectionCheckerWorkRequest);
问题:
在某些情况下没有显示通知,并且在 android 11+ 设备中,它会在我打开应用程序后显示。
解决方案
从我可以判断的情况来看,您的 WorkManager 很可能被关闭,并且一旦您重新打开应用程序,计划任务就会运行。
这是 WorkManager 的一个已知问题,它实际上不是 WorkManager 问题,而是操作系统问题。WorkManager 的行为如下:
任务管理器关闭: 工作继续(稍后)
重启设备(工作运行): 重启完成后工作继续
应用程序信息“强制停止”: 工作停止,只有重新启动应用程序才会继续
重启设备(工作被“强制停止”): 直到应用程序再次启动,工作才会继续
问题是某些设备会从最近的菜单中杀死应用程序作为强制停止。默认情况下,大多数流行的应用程序都被列入操作系统的白名单。可能有一种解决方法可以让用户将您的应用列入白名单,尽管我认为这不是一个合适的解决方法。
推荐阅读
- angular - AngularFIre:限制为 10 个最近的寄存器
- javascript - 循环只返回一个元素
- html - 社交图标彼此不对齐 - css/html
- r - 如果该单词包含在相应行的句子中,则在列中插入向量值(test_condition)
- javascript - Javascript将数组中的元素分配给不同的值
- c++ - 如何避免`std::to_string()`将一个非常小的双数变为0?
- ios - UIButton 属性观察者 didset 从未调用过
- python - 致命错误:cuda_runtime_api.h:尝试在 docker 中使用 cuda 时没有这样的文件或目录
- html - 如何增加箭头进度条 CSS 的高度
- java - Java反应器如何正确启动异步可取消的副作用