Reputation: 113
I am facing a problem when scheduling multiple (up to 14) notifications using the AlarmManager. The problem is that the notifications are randomly missing (especially when the debug cable isn’t plugged). For example the first three notifications are triggered and after these notifications none of the scheduled notifications get triggered anymore, until you reschedule the notifications. It seems it’s because of the amount of notifications, but I am not 100% sure.
Below you can find my functions for scheduling notifications (alarm and bedtime notifications);
private fun createNotificationChannel(name: String, descriptionText: String, id: String, setSound:Boolean)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(id, name, importance).apply {
description = descriptionText
}
val audioAttributes = AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
if (setSound)
{
channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + m_context.packageName + "/" + m_ringtone), audioAttributes)
}
(m_context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).createNotificationChannel(channel)
}
}
private fun createBedTimeNotificationChannel()
{
createNotificationChannel(BEDTIME_NOTIFICATION_CHANNEL_NAME, BEDTIME_NOTIFICATION_CHANNEL_DESCRIPTION, BEDTIME_NOTIFICATION_CHANNEL, false)
}
private fun createWakeUpNotificationChannel()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
for (channel in (m_context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).notificationChannels)
{
if (channel.id.contains(WAKE_UP_ALARM_NOTIFICATION_CHANNEL))
{
(m_context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).deleteNotificationChannel(channel.id)
}
}
m_randomNumber = Random().nextLong()
createNotificationChannel(WAKE_UP_NOTIFICATION_CHANNEL_NAME, WAKE_UP_NOTIFICATION_CHANNEL_DESCRIPTION, WAKE_UP_ALARM_NOTIFICATION_CHANNEL + m_randomNumber, true)
}
}
fun configureAlarmNotification(ringtone: Int, alarmTime: Int, snooze: Boolean, days: BooleanArray)
{
m_ringtone = ringtone
createWakeUpNotificationChannel()
for ((index, alarmOn) in days.withIndex())
{
if (alarmOn)
{
val builder = getWakeUpAlarmBuilder()
val intent = Intent(m_context, CMainActivity::class.java)
val activity = PendingIntent.getActivity(m_context, WAKE_UP_NOTIFICATION_ID_START + index + 1, intent, PendingIntent.FLAG_UPDATE_CURRENT)
builder.setContentIntent(activity)
if (snooze)
{
val snoozeIntent = Intent(m_context, CSleepPlannerService::class.java).apply {
putExtra(ACTION, ACTION_SNOOZE)
putExtra(NOTIFICATION_ID, WAKE_UP_NOTIFICATION_ID_START + index + 1)
putExtra(NOTIFICATION, builder.build())
}
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(m_context, SNOOZE_PRESSED_NOTIFICATION_ID + index + 1, snoozeIntent, 0)
builder.addAction(R.drawable.alarm_bel_icon, m_context.getString(R.string.snooze), snoozePendingIntent)
}
val notification = builder.build()
val calendar = Calendar.getInstance()
val currentTimeInMillis = calendar.timeInMillis
calendar[Calendar.DAY_OF_WEEK] = convertWeekday(index)
calendar[Calendar.HOUR_OF_DAY] = alarmTime / 60
calendar[Calendar.MINUTE] = alarmTime % 60
calendar[Calendar.SECOND] = 0
if (calendar.timeInMillis <= currentTimeInMillis)
{
calendar.timeInMillis += NUMBER_OF_MILLIS_IN_WEEK
}
val pendingIntent = getPendingIntent(calendar.timeInMillis, WAKE_UP_NOTIFICATION_ID_START + index + 1, notification, ACTION_NOTIFICATION, PendingIntent.FLAG_UPDATE_CURRENT)
(m_context.getSystemService(ALARM_SERVICE) as AlarmManager).setExact(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
}
}
val calendar = Calendar.getInstance()
m_alarmWithSoundEnabledWithinADay.postValue((m_preferences.isAlarmWithSoundEnabled() && isAlarmEnabled(calendar[Calendar.HOUR_OF_DAY] * 60 + calendar[Calendar.MINUTE], m_preferences.getAlarmTime(), calendar[Calendar.DAY_OF_WEEK])))
}
fun configureBedTimeNotification(bedTime: Int, bedTimeSetting: Int, days: BooleanArray)
{
for ((index, alarmOn) in days.withIndex())
{
if (alarmOn)
{
val builder = NotificationCompat.Builder(m_context, BEDTIME_NOTIFICATION_CHANNEL).apply {
setContentTitle(m_context.getString(R.string.bedtime_notification_tile))
when (BedTimeNotificationSetting_e.fromInt(bedTimeSetting))
{
BedTimeNotificationSetting_e.AT_BED_TIME -> setContentText(m_context.getString(R.string.bedtime_notification_at_bedtime))
BedTimeNotificationSetting_e.TEN_MINUTES_BEFORE -> setContentText(m_context.getString(
R.string.bedtime_notification_description_ten
))
BedTimeNotificationSetting_e.THIRTY_MINUTES_BEFORE -> setContentText(m_context.getString(R.string.bedtime_notification_description_thirty))
BedTimeNotificationSetting_e.FORTYFIVE_MINUTES_BEFORE -> setContentText(m_context.getString(R.string.bedtime_notification_description_fortyfive))
BedTimeNotificationSetting_e.SIXTY_MINUTES_BEFORE -> setContentText(m_context.getString(R.string.bedtime_notification_description_sixty))
}
setAutoCancel(true)
setSmallIcon(R.drawable.alarm_icon)
priority = NotificationCompat.PRIORITY_HIGH
}
val intent = Intent(m_context, CMainActivity::class.java)
val activity = PendingIntent.getActivity(m_context, BEDTIME_NOTIFICATION_ID_START + index + 1, intent, PendingIntent.FLAG_UPDATE_CURRENT)
builder.setContentIntent(activity)
val notification = builder.build()
val calendar = Calendar.getInstance()
val currentTimeInMillis = calendar.timeInMillis
calendar[Calendar.DAY_OF_WEEK] = convertWeekday(index)
calendar[Calendar.HOUR_OF_DAY] = bedTime / 60
calendar[Calendar.MINUTE] = bedTime % 60
calendar[Calendar.SECOND] = 0
var newBedTime = calendar.timeInMillis - (bedTimeSetting * 60 * 1000)
if (newBedTime <= currentTimeInMillis)
{
newBedTime += NUMBER_OF_MILLIS_IN_WEEK
}
val pendingIntent = getPendingIntent(newBedTime, BEDTIME_NOTIFICATION_ID_START + index + 1, notification, ACTION_NOTIFICATION, PendingIntent.FLAG_UPDATE_CURRENT)
(m_context.getSystemService(ALARM_SERVICE) as AlarmManager).setExact(AlarmManager.RTC_WAKEUP, newBedTime, pendingIntent)
}
}
}
private fun getPendingIntent(calendarTime: Long = 0, notificationId: Int, notification: Notification? = null, action: String, flag: Int) : PendingIntent?
{
val notificationIntent = Intent(m_context, this::class.java)
notificationIntent.putExtra(ACTION, action)
notificationIntent.putExtra(NOTIFICATION_ID, notificationId)
notificationIntent.putExtra(NOTIFICATION, notification)
notificationIntent.putExtra(ALARM_TIME, calendarTime)
return PendingIntent.getBroadcast(m_context, notificationId, notificationIntent, flag)
}
What could be the cause of this?
Upvotes: 1
Views: 83
Reputation: 113
I fixed the issue for setting the wakeup notifications by using the function setAlarmClock from AlarmManager.
Upvotes: 0
Reputation: 4112
It is difficult to know exactly what could be wrong. Depending on the version of the system, Android might decide to wait / delay / group notifications. The amount of battery left also impact the decision to show a notif.
I see that you use setPriority
on the notification builder with a HIGH
value. This should work for android < api 26. For newer versions, it is the setImportance
in the notification channel that will be taken in account
val importance = NotificationManager.IMPORTANCE_HIGH
// edit your code like this in createNotificationChannel, you currently use DEFAULT
Upvotes: 1