Reputation: 117
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
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