'Schedule periodic local notification based on specific dates

I want to make a periodic worker to schedule notifications based on the total number of customer collection dates. I already did apart, but I'm facing a problem.

Objective:
Check if there is a customer with tomorrow's collection date, then schedule a notification to be shown tomorrow at 10 am to remind the user, and repeat the same thing every day.

Work I did:
First of all, I worked on this solution based on a periodic work manager.

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);


    }

AlarmBroadcast.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);

Problem:
notification is not showing in some cases, and in android 11+ devices it shows after I open the app.



Solution 1:[1]

From what I can judge of the situation it is most likely that your WorkManager is being closed off and as soon as you reopen the app the scheduled task runs.

This is a known issue of WorkManager which is not really a WorkManager issue but an OS issue. The behavior for WorkManager is as follows:

Task manager close: Work continues (after a bit)

Reboot device (work running): Work continues after reboot done

App info "Force stop": Work stops, will only continue when app is started again

Reboot device (work was "Force Stopped"): Work does not continue until the app is started again

And the problem with this is some devices implement killing the app from the recents menu as a force stop. Most popular apps are whitelisted by default for the OS. There might be a workaround which can include user to whitelist your app maybe although I don't think that is a proper one.

You can fine more discussion here and here too for some further idea.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 che10