I'm developing an app that list upcoming movies and allows the user to create a reminder for a specific upcoming movie.
Once the user click on the reminder button of a movie the app should schedule 3 notifications at once:
- One notification 6 days before the release date of the movie;
- One notification 2 days before the release date of the movie and
- One notification on the day of the movies's release
I'm using AlarmManager + Broadcast and i'm not receiving any of the notifications mentioned above, but if I schedule a notification for the next hours the app sends the notification. I'm deducing that it's something about scheduling a notification from the next day onwards.
Searching in the Internet i've found some stackoverflow threads that said that the device could be cleaning the scheduleds alarms (something related to battery saving), but i've found nothing on that topic in the android documentation.
I've also tried to use WorkManager but i'm also getting the same behavior from AlarmManager, besides.. I think that the way to go should be AlarmManager, since i'm simply trying to schedule local notification.
Here is the code i'm using: manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.cinema">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".application.CinemaApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Cinema"
tools:targetApi="31">
<receiver android:name="com.example.common.broadcast.MovieReminderBroadcast"/>
<activity
android:name=".MainAppActivity"
android:exported="true">
...
</activity>
</application>
</manifest>
CinemaReminderManagerImpl.kt
val alarmManager = context.getSystemService(AlarmManager::class.java)
val intent = Intent(context, MovieReminderBroadcast::class.java).apply {
putExtra("deeplink", deeplink)
putExtra("message", "message")
putExtra("notificationId", movieId)
}
val pendingIntent = PendingIntent.getBroadcast(
context,
movieId,
intent,
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT } else { PendingIntent.FLAG_UPDATE_CURRENT }
)
alarmManager.set(
AlarmManager.RTC_WAKEUP,
timeInMillis,
pendingIntent
)
MovieReminderBroadcast.kt
class MovieReminderBroadcast : BroadcastReceiver() {
companion object {
private const val CHANNEL_ID = "ReminderNotificationChannel"
}
override fun onReceive(context: Context?, receiverIntent: Intent?) {
if (context == null) return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_ID,
NotificationManager.IMPORTANCE_DEFAULT
).apply {
description = "Reminder Channel Description"
}
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
val deeplink = receiverIntent?.extras?.getString("deeplink").orEmpty()
val message = receiverIntent?.extras?.getString("message").orEmpty()
val notificationId = receiverIntent?.extras?.getInt("notificationId") ?: 0
val intent = Intent().apply {
action = Intent.ACTION_VIEW
data = Uri.parse(deeplink)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent = PendingIntent.getActivity(
context,
notificationId,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
.setAutoCancel(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(
context.resources.getString(R.string.common_title_notification)
)
.setContentText(
message
)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.build()
NotificationManagerCompat.from(context).notify(notificationId, notification)
}
}