Background: we created an app that is used for tracking your working hours, you press Check in when you arrive and Check out when you leave. We thought that it would be nice if the user could set reminders to check-in or out. As we need data about the user's current check-in state in order to display the right text, we can't just schedule the notifications, we need to fetch that data from the online database first and then decide what to display, therefore we need a WorkManager.
Sometimes one notification (time to check-in) doesn't show, despite log message about the background work being successful, and another one that was supposed to display after (time to check out) displays.
I'm using Samsung Galaxy S9+ with the latest updates (Android 9).
I tried checking scheduled jobs via ADB. Sometimes they are there with correct delays and everything, sometimes they aren't there at all, but notifications arrive anyway, so that's not all that reliable.
I went through the scheduling using debugger at every case I have covered and everything got set up exactly as I expected: the new shift is added to the array and populated with expected data, work is scheduled at the correct time. When edited, old work is canceled by UUID, a new one is created. On delete, work is canceled and the shift is set to null.
First, I need to schedule the work for a specific shift. Shift
has attributes shiftFrom
, shiftTo
and UUIDs of scheduled notifications for those times. In order to schedule the workers, I have a NotificationScheduler
class with scheduleWeekly
method in which I determine the delays and then I schedule the work:
val sendNotificationRequest = PeriodicWorkRequestBuilder<NotificationsWorker>(7, TimeUnit.DAYS)
.setInputData(
workDataOf(
NotificationsWorker.TITLE_PARAM to title,
NotificationsWorker.CONTENT_PARAM to content,
NotificationsWorker.ACTION to action // this tells the worker wheter the user is supposed to check in or check out when it's triggered
)
)
.setInitialDelay(initialDelayMinutes, TimeUnit.MINUTES) // wanted time - current time converted to minutes
.build()
WorkManager.getInstance(context).enqueue(sendNotificationRequest)
When triggered, it calls NotificationsWorker
. Based on the current check-in state and whether the user is supposed to check-in or out I decide which text I'm going to display in the notification. Also, the log message created by me is logged - the work indeed is triggered at the correct time.
Then I send a notification using this method:
private fun sendNotification(title: String, content: String) {
val notificationIntent = Intent(context, SplashActivity::class.java) // for when the notification is clicked
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
val intent = PendingIntent.getActivity(
context, 0,
notificationIntent, 0
)
val builder =
NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(package.appname.R.drawable.ic_app_icon)
.setContentTitle(title)
.setContentText(content)
.setContentIntent(intent)
.setAutoCancel(true)
.setStyle(NotificationCompat.BigTextStyle().bigText(content))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
with(NotificationManagerCompat.from(context)) {
notify(0, builder.build())
}
}
What I expect is for notifications to arrive +-10 minutes from when they were scheduled and mostly that is what happens, but sometimes they don't arrive at all and sometimes I get them at really weird times (for example, I got one saying I was supposed to check-in at 22:12 on Saturday, but the shifts were scheduled 8-16, Monday to Friday).
Also, the mentioned notification on Saturday somehow managed to acquire data about my check-in the state, but I had no internet connection and currently notifications receive no local data whatsoever.