I have never scheduled notifications before and need help. My app have Notification entity which contains:
@Parcelize
@Entity
data class Notification(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
var time: Date,
var daysOfWeek: Set<DayOfWeek>,
var enabled: Boolean = false
) : Parcelable
I wish to let this notification trigger selected days of week in specified time. I also have several methods to set notifications:
private fun codeForNotification(notification: Notification, dayOfWeek: DayOfWeek) =
1000 + notification.id * 10 + dayOfWeek.ordinal
fun checkNotification(notification: Notification, isEnabled: Boolean? = null) = with(notification) {
if ((isEnabled == null && enabled) || isEnabled == true) daysOfWeek.forEach { dow ->
setNotification(time, dow, codeForNotification(this, dow))
} else daysOfWeek.forEach { dow ->
Intent(appContext, NotificationReceiver::class.java).let { intent ->
PendingIntent.getBroadcast(
appContext,
codeForNotification(this, dow),
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}.let(alarmManager::cancel)
}
}
fun setNotification(time: Date, dayOfWeek: DayOfWeek, code: Int) {
c2.time = time
c1.apply {
this.time = Date()
set(Calendar.HOUR_OF_DAY, c2.get(Calendar.HOUR_OF_DAY))
set(Calendar.MINUTE, c2.get(Calendar.MINUTE))
}
c1.set(Calendar.DAY_OF_WEEK, dayOfWeek.calendarValue)
if (c1.timeInMillis < System.currentTimeMillis()) {
c1.add(Calendar.DAY_OF_YEAR, 7)
}
Intent(appContext, NotificationReceiver::class.java).let {
PendingIntent.getBroadcast(appContext, code, it, PendingIntent.FLAG_CANCEL_CURRENT)
}.let {
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
c1.timeInMillis,
AlarmManager.INTERVAL_DAY * DayOfWeek.values().size,
it
)
}
}
Notifications are set similarly to the question (using check notification), but they do not fire.
My receiver class:
class NotificationReceiver : BroadcastReceiver() {
companion object {
const val CHANNEL_ID = "CHANNEL"
const val NOTIFY_ID = 1111
}
override fun onReceive(context: Context?, intent: Intent?) = context?.let{
val builder: NotificationCompat.Builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle("Notification")
.setContentText("Hello world")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
val notificationManager =
NotificationManagerCompat.from(context)
notificationManager.notify(NOTIFY_ID, builder.build())
} ?: Unit
}
And manifest have :
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".main.notification.NotificationReceiver" />
Please help me!
Setting notification channel fixed this issue:
override fun onReceive(context: Context?, intent: Intent?) = context?.run {
val notificationManager: NotificationManager? =
getSystemService(this, NotificationManager::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationManager?.let(::setNotificationChanel)
Notification.Builder(context, CHANNEL_ID)
} else {
Notification.Builder(context)
}.setSmallIcon(R.drawable.ic_access_alarm_24px)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.notification_description))
.setContentIntent(getActivityIntent(this))
.setAutoCancel(true)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_access_alarm_24px))
.build().let { notification ->
notificationManager?.notify(NOTIFICATION_ID, notification)
}
} ?: Unit
@RequiresApi(Build.VERSION_CODES.O)
private fun setNotificationChanel(notificationManager: NotificationManager) =
NotificationChannel(CHANNEL_ID, CHANNEL_ID, NotificationManager.IMPORTANCE_HIGH).apply {
description = CHANNEL_DESC
enableLights(true)
lightColor = Color.RED
enableVibration(true)
setShowBadge(true)
}.let(notificationManager::createNotificationChannel)