A common situation that as Android Developers we deal with is keeping our app’s users up-to-date with what is going on when they are not using our app. The Android SDK provides us with a fully integrated API to do this: Notifications.
Notifications are messages that developers can program and send to the OS to be shown outside of our amazing UI so if the user is not using the app, he or she won’t miss an important event. Sometimes, our app may send a lot of notifications that can affect how the user perceives our features, potentially leading to losing them as our costumers because they are receiving meaningless information. However, with this new level API we have now the tools to let the users manage this issue.
Notifications can be used in several situations:
- Show reminders.
- Inform the users about a new promotional code/price for a service our app provides.
- Tell them that some long running operation has been finished successfully or if an error occurred.
- Inform the users that something they were expecting to happen, has already happened.
- Anything you can imagine that needs to gain user attention. Imagination is the limit!!!
How do we use them?
Since Android 8.0+ new changes were introduced to the API. In order to be sure our app is compatible with the new & old versions of the OS our explanation will be based on this API level. Regardless this restriction, we are going to use the *NotificationCompat* & *NotificationManagerCompat* classes from the SDK so you can get the sample up & running on prior versions without tying the Notifications to a particular channel.
The first thing you need to create is a Notification Channel, which in essence is a way to group your notifications by topic. This will offer the user the possibility for fine-grained control over notifications.
Here we are only creating one channel to group all our notifications but you can use a channel for each major topic/subject your app internally handles. For example, a channel could show sales news and another display order tracking data. As you can see, the above code snippet uses @Inject & @ApplicationScope, which are Dagger (2.13) annotations to indicate that this class can be instantiated only once (singleton pattern) and can be injected on our app components.
Next, we have to place notifications on our channels. To do this, we use Kotlin Sealed Classes to create a common interface so we can create our notifications according to the type and actions needed. Also, we can reuse code for future implementations.
We’ll use these models in the next Factory to build the OS notifications in a customized and centralized way.
This class does two things well. First, it creates an OS Notification Object based on the classes that extend from *SkeletalNotification*. Second, it delivers this notification to the system to be displayed on the status bar so that the user can interact with the app even when it is in the background. On prior versions of Android 8.0, the *NotificationCompat* ignores the assigned channel to the notification in order to deliver and display the notification.
- Even when notifications are very useful, try not to overwhelm the user with them. When the amount of notifications increases, it could be annoying and we don’t want our users to leave our app.
- Always use the *NotificationCompat* class to build notifications. This class will put the notifications inside the right channel when running on devices with Android 8.0+ and will be compatible with versions that don’t support them.
- Create enough channels to let your users disable only the notifications they are not interested in. Be careful and separate them correctly so users don’t lose important notifications.
Full code is hosted here, go over the notifications recipe inside the cookbook package.