首页 > 解决方案 > 根据特定日期安排定期本地通知

问题描述

我想让一个定期工作人员根据客户收集日期的总数安排通知。我已经分开了,但我面临一个问题。

目标:
检查是否有明天取货日期的客户,然后安排在明天上午 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+ 设备中,它会在我打开应用程序后显示。

标签: javaandroidandroid-jetpackandroid-workmanager

解决方案


从我可以判断的情况来看,您的 WorkManager 很可能被关闭,并且一旦您重新打开应用程序,计划任务就会运行。

这是 WorkManager 的一个已知问题,它实际上不是 WorkManager 问题,而是操作系统问题。WorkManager 的行为如下:

任务管理器关闭: 工作继续(稍后)

重启设备(工作运行): 重启完成后工作继续

应用程序信息“强制停止”: 工作停止,只有重新启动应用程序才会继续

重启设备(工作被“强制停止”): 直到应用程序再次启动,工作才会继续

问题是某些设备会从最近的菜单中杀死应用程序作为强制停止。默认情况下,大多数流行的应用程序都被列入操作系统的白名单。可能有一种解决方法可以让用户将您的应用列入白名单,尽管我认为这不是一个合适的解决方法。

您可以在此处此处进行更多讨论以获取更多想法。


推荐阅读