Amine Karimi
Amine Karimi

Reputation: 117

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.

Upvotes: 1

Views: 148

Answers (1)

che10
che10

Reputation: 2318

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.

Upvotes: 1

Related Questions