These days, most startup apps heavily rely on third-party libraries to send push notifications to a user, thus causing developers to usually not pay too much attention to Android notification changes.
For example, I was working on my side-project which sends a notification once the download is completed (was checking how DownloadManager works).
Back in 2016, you’d need to initialize NotificationManager and pending intent if notification contains custom action:
1private lateinit var notificationManager: NotificationManager
2private lateinit var pendingIntent: PendingIntent
3
4override fun onCreate(savedInstanceState: Bundle?) {
5 ...
6 notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
7
8 val intent = Intent(this, DetailActivity::class.java)
9 pendingIntent =
10 PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT)
11}
And then after download is complete, you’d need to build the notification, include pendingIntent and send it to notification manager:
1val builder = NotificationCompat.Builder(context)
2 .setSmallIcon(R.drawable.ic_assistant_black_24dp)
3 .setContentTitle(getString(R.string.notification_title))
4 .setContentText(getString(R.string.notification_description))
5 .setPriority(NotificationCompat.PRIORITY_MAX)
6 .addAction(R.drawable.icon, getString(R.string.notification_button), pendingIntent)
7
8notificationManager.notify(1, builder.build())
After writing code and running the app, the notification wasn’t getting displayed. I thought maybe I was incorrectly implementing DownloadManager since I had just started playing around with it. So, after some debugging, I saw that the DownloadManager worked flawlessly and notificationBuilder did in-fact get called, but nothing was displayed 🤦. The next obvious step was to google the issue. The first stackOverflow answer mentioned the following change in NotificationManager for Android O and above.
💡So for the devices running on Android O and above, it’s required to create a channel for different kind of notifications where id, name and importance should be passed in constructor:
override fun onCreate(savedInstanceState: Bundle?) {
...
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
getString(R.string.notification_title),
NotificationManager.IMPORTANCE_HIGH
)
notificationManager.createNotificationChannel(channel)
}
}
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
Made the changes, the notification got displayed!
But the action button didn’t work 😒. After another round of googling, I found out the addAction
method in notificationBuilder now requires an Action
class, which is basically a wrapper of the arguments addAction
method used to accept.
The full code of sending and displaying notifications nowadays is below:
private lateinit var notificationManager: NotificationManager
private lateinit var action: NotificationCompat.Action
override fun onCreate(savedInstanceState: Bundle?) {
...
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
getString(R.string.notification_title),
NotificationManager.IMPORTANCE_HIGH
)
notificationManager.createNotificationChannel(channel)
}
val intent = Intent(this, DetailActivity::class.java)
val pendingIntent =
PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT)
action = NotificationCompat.Action.Builder(
R.drawable.icon, getString(R.string.notification_button), pendingIntent
).build()
}
...
private fun downloadCompleted() {
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_assistant_black_24dp)
.setContentTitle(getString(R.string.notification_title))
.setContentText(getString(R.string.notification_description))
.setPriority(NotificationCompat.PRIORITY_MAX)
.addAction(action)
notificationManager.notify(1, builder.build())
}
Hopefully, this article was helpful and stay tuned for another then-and-now article!