Android O: How to Use Notification Channels

Google has launched the first developer preview of the next Android version, currently code-named Android O (Oreo maybe?). Some exciting features were released, and one of them is Notification Channels. In this tutorial, we’ll explore this feature and build a simple app that demonstrates the functionalities it provides.

Android O: How to Use Notification Channels

Android O: How to Use Notification Channels

What Are Notification Channels?

Notification channels enable us app developers to group our notifications into groups—channels—with the user having the ability to modify notification settings for the entire channel at once. For example, for each channel, users can completely block all notifications, override the importance level, or allow a notification badge to be shown. This new feature helps in greatly improving the user experience of an app.

We’re going to learn about this feature by building a simple application called “TutsplusAlerts” that will provide two notification channels: Android and iOS. The user will receive a notification from one of these separate channels whenever a new article is submitted.

1. Set Up the Android O SDK

To begin to use Android O APIs as of this writing, you will need to have the latest Android Studio 2.4 Canary installed on your computer.

Launch Android Studio 2.4 and open the SDK Manager by clicking Tools > Android > SDK Manager.

Then, in the SDK Platforms tab, check Show Package Details. Below Android O Preview, check the following: Android SDK Platform O and Google APIs Intel x86 Atom System Image (required only for the emulator).

Android O: How to Use Notification Channels

Then switch to the SDK Tools tab, and select the following:

  • Android SDK Build-Tools 26.0.0 (rc1 or higher)
  • Android SDK Platform-Tools 26.0.0 (rc1 or higher)
  • Android Emulator 26.0.0
  • Support Repository

Click the OK button to download all of these components.

2. Create an Android Studio Project

In your Android Studio, create a new project named TutsplusAlerts with an empty activity called MainActivity.

Android O: How to Use Notification Channels

3. Update build.gradle

Go to your app module build.gradle file and update compileSdkVersion, buildToolsVersion and targetSdkVersion and finally the Support Library version.

android {
    compileSdkVersion "android-O"
    buildToolsVersion "26.0.0-rc1"

    defaultConfig {
        applicationId "com.chikeandroid.tutsplusalerts"
        minSdkVersion 'O'
        targetSdkVersion 'O'
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  }
  ...
}

dependencies {
    ...
    compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
    ...
}

Remember to sync your project after making these changes.

4. Create Notification Channels

Create a new class and name it NotificationUtils, extending ContextWrapper.

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Color;

public class NotificationUtils extends ContextWrapper {

    private NotificationManager mManager;
    public static final String ANDROID_CHANNEL_ID = "com.chikeandroid.tutsplustalerts.ANDROID";
    public static final String IOS_CHANNEL_ID = "com.chikeandroid.tutsplustalerts.IOS";
    public static final String ANDROID_CHANNEL_NAME = "ANDROID CHANNEL";
    public static final String IOS_CHANNEL_NAME = "IOS CHANNEL";

    public NotificationUtils(Context base) {
        super(base);
        createChannels();
    }

    public void createChannels() {

        // create android channel
        NotificationChannel androidChannel = new NotificationChannel(ANDROID_CHANNEL_ID,
                ANDROID_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
        // Sets whether notifications posted to this channel should display notification lights
        androidChannel.enableLights(true);
        // Sets whether notification posted to this channel should vibrate.
        androidChannel.enableVibration(true);
        // Sets the notification light color for notifications posted to this channel
        androidChannel.setLightColor(Color.GREEN);
        // Sets whether notifications posted to this channel appear on the lockscreen or not
        androidChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);

        getManager().createNotificationChannel(androidChannel);

        // create ios channel
        NotificationChannel iosChannel = new NotificationChannel(IOS_CHANNEL_ID,
                IOS_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
        iosChannel.enableLights(true);
        iosChannel.enableVibration(true);
        iosChannel.setLightColor(Color.GRAY);
        iosChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        getManager().createNotificationChannel(iosChannel);
    }

    private NotificationManager getManager() {
        if (mManager == null) {
            mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return mManager;
    }
}

In the code above, we created two instances of the NotificationChannel, passing an id (which must be unique within your package), a channel name, and also an importance level in its constructor. For each notification channel, we applied characteristics such as sound, lights, vibration, and a notification to show on the lock screen. Finally, we got the NotificationManager from the system and then registered the channel by calling the method createNotificationChannel(), passing the channel we have created.

We can create multiple notification channels all at once with createNotificationChannels(), passing a Java list of NotificationChannel instances. You can get all notification channels for an app with getNotificationChannels() and get a specific channel with getNotificationChannel(), passing only the channel id as an argument.

Importance Levels

Starting from Android O, priority levels are deprecated for individual notifications. Instead, you set an importance level when creating a notification channel—ranging from NotificationManager.IMPORTANCE_NONE to NotificationManager.IMPORTANCE_HIGH.  We’ll set the Android channel to be IMPORTANCE_DEFAULT, while that of the iOS channel will be IMPORTANCE_HIGH.

The full list of importance options available are:

  • IMPORTANCE_MAX: unused
  • IMPORTANCE_HIGH: shows everywhere, makes noise and peeks
  • IMPORTANCE_DEFAULT: shows everywhere, makes noise, but does not visually intrude
  • IMPORTANCE_LOW: shows everywhere, but is not intrusive
  • IMPORTANCE_MIN: only shows in the shade, below the fold
  • IMPORTANCE_NONE: a notification with no importance; does not show in the shade

All notifications for a channel will be given the same importance level.

5. Create Notifications and Post to Channels

We are going to create two Notifications for each of our channels in the NotificationUtils class we created. We specify which notification should be sent to a channel in the Notification.Builder (Android API 25) constructor, where we pass it the channel id as the second argument.

// ...
public Notification.Builder getAndroidChannelNotification(String title, String body) {
    return new Notification.Builder(getApplicationContext(), ANDROID_CHANNEL_ID)
            .setContentTitle(title)
            .setContentText(body)
            .setSmallIcon(android.R.drawable.stat_notify_more)
            .setAutoCancel(true);
}

public Notification.Builder getIosChannelNotification(String title, String body) {
    return new Notification.Builder(getApplicationContext(), IOS_CHANNEL_ID)
            .setContentTitle(title)
            .setContentText(body)
            .setSmallIcon(android.R.drawable.stat_notify_more)
            .setAutoCancel(true);
}
//...

Be aware that Notification.Builder() also has a notification channel id setter method called setChannel(String channelId), so you can choose to set the notification channel id either in the constructor or using the setter method.

6. Create the XML Layout

Now that we have the setup for creating and posting to notification channels, let’s create the XML layout interface for posting the message in our activity_main.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_margin="16dp"
        tools:context="com.chikeandroid.tutsplusalerts.MainActivity">

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Tuts+ Android Channel"
                android:layout_gravity="center_horizontal"
                android:textAppearance="@style/TextAppearance.AppCompat.Title"/>

        <EditText
                android:id="@+id/et_android_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Title"/>

        <EditText
                android:id="@+id/et_android_author"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Author"/>
        
        <Button
                android:id="@+id/btn_send_android"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Send"/>
    </LinearLayout>

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_marginTop="20dp">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Tuts+ IOS Channel"
                android:layout_gravity="center_horizontal"
                android:textAppearance="@style/TextAppearance.AppCompat.Title"/>

        <EditText
                android:id="@+id/et_ios_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Title"
                />

        <EditText
                android:id="@+id/et_ios_author"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Author"/>
        <Button
                android:id="@+id/btn_send_ios"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Send"/>
    </LinearLayout>
    
</LinearLayout>

7. Post Notifications to Channels

Posting to Android Channel

In this section, we are going to edit our MainActivity so that we can get the title and author from the EditText components and then send these to the Android channel. We get the Notification.Builder for the Android channel we created in our NotificationUtils, and then notify the NotificationManager.

import android.app.Notification;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    private NotificationUtils mNotificationUtils;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNotificationUtils = new NotificationUtils(this);

        final EditText editTextTitleAndroid = (EditText) findViewById(R.id.et_android_title);
        final EditText editTextAuthorAndroid = (EditText) findViewById(R.id.et_android_author);
        Button buttonAndroid = (Button) findViewById(R.id.btn_send_android);

        buttonAndroid.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String title = editTextTitleAndroid.getText().toString();
                String author = editTextAuthorAndroid.getText().toString();

                if(!TextUtils.isEmpty(title) && !TextUtils.isEmpty(author)) {
                    Notification.Builder nb = mNotificationUtils.
                            getAndroidChannelNotification(title, "By " + author);

                    mNotificationUtils.getManager().notify(101, nb.build());
                }
            }
        });
    }
}

At this point, run the app and enter a title and an author, and then click the send button to receive the notification immediately.

Android O: How to Use Notification Channels

Posting to the iOS Channel

Here we would post to the iOS channel. We get the Notification.Builder for the iOS channel we created in our NotificationUtils and then call the notify() method in the NotificationManager.

@Override
protected void onCreate(Bundle savedInstanceState) {
   
    // ...
    
    final EditText editTextTitleIos = (EditText) findViewById(R.id.et_ios_title);
    final EditText editTextAuthorIos = (EditText) findViewById(R.id.et_ios_author);
    Button buttonIos = (Button) findViewById(R.id.btn_send_ios);
    buttonIos.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String title = editTextTitleIos.getText().toString();
            String author = editTextAuthorIos.getText().toString();

            if(!TextUtils.isEmpty(title) && !TextUtils.isEmpty(author)) {
                Notification.Builder nb = mNotificationUtils
                        .getIosChannelNotification(title, "By " + author);

                mNotificationUtils.getManager().notify(102, nb.build());
            }
        }
    });
}

Run the app again and enter a title and an author, and then click the send button to receive the notification immediately.

Android O: How to Use Notification Channels

8. Notification Channel Settings

As of this writing, you can’t programmatically change the configuration of specific notification channel settings. Instead, the only option available is for the user to go to the notification settings screen for the app in the device settings. From there, the user can access the app notification settings to modify settings such as vibration, sound, etc. Users can navigate to the app notification settings in either of the following ways:

  • Long pressing on the notification on the notification drawer (left image below).
  • Settings > Apps & notifications > Notifications > then selecting the app (right image below).

Android O: How to Use Notification Channels

You can also send the user right from your app to the channel notification settings. Let’s see how we can do that for the Android channel. It’s recommended that you do this in your app settings to make it easy for users to access these notification options.

Edit the XML Layout

Include another button that will send the user to the channel notification settings.

<!--...-->
<Button
    android:id="@+id/btn_android_notif_settings"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Notification Settings"/>
<!--...-->

Code the Intent

Here we create an intent and pass it a Settings action—ACTION_CHANNEL_NOTIFICATION_SETTINGS (API 25)—and then add some extra values: the app package name and channel id. Finally, we start the settings activity with the intent.

// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
    //...
    Button buttonAndroidNotifSettings = (Button) findViewById(R.id.btn_android_notif_settings);
    buttonAndroidNotifSettings.setOnClickListener(new View.OnClickListener() {
    
        @Override
        public void onClick(View view) {
            Intent i = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
            i.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
            i.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationUtils.ANDROID_CHANNEL_ID);
            startActivity(i);
        }
    });
}
//...

Run the app and click the notification settings for the Android channel.

Android O: How to Use Notification Channels

In the channel notification settings, users can edit settings such as enabling vibrations, changing the importance, or showing a badge (if supported) for the channel.

If you want to take users to the general notification settings for your app, you can also do that with an Intent:

Intent i = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
i.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
startActivity(i);

9. Create Notification Groups

We can also group notification channels into groups so they can be managed together. This is useful for apps that support multiple user accounts. The same notification channels are available across the individual accounts. For example, a social networking app might include support for both personal and business user accounts. The code below shows you how to create a notification channel group:

String groupId = "group_id_101";
CharSequence groupName = "Channel Name";
NotificationManager mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannelGroup(new NotificationChannelGroup(groupId, groupName));

We used the NotificationManager createNotificationChannelGroup() method, passing it an instance of NotificationChannelGroup, which needs the group id and group name to create the instance.

Once that is done, we need to connect a notification channel to a group by using the NotificationChannel.setGroup() method and passing it the group id. If you want to create multiple notification groups all at once, use createNotificationChannelGroups(), passing it a Java list of NotificationChannelGroup instances.

10. Delete a Notification Channel

Deleting a notification channel is easy if it is no longer needed. Just use the notification manager method deleteNotificationChannel() and pass the channel id.

NotificationManager mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.deleteNotificationChannel(IOS_CHANNEL_ID);

However, be aware that deleted channels remain visible in the notification settings so as to prevent spam.

Conclusion

In this tutorial, you learned about Notification Channels for Android O: what they are and how to create one, as well as how to post a notification to a channel, how to access a channel’s notification settings, how to group notification channels, and how to delete a notification channel.

To learn more about Notification Channels, do refer to the official documentation. And in the meantime, check out some of our other courses and tutorials on Android app development!

  • Android O: How to Use Notification Channels
    Android SDK
    Quick Tip: Create Autosizing Text With Android O
    Jessica Thornsby
  • Android O: How to Use Notification Channels
    Android SDK
    Code an Image Gallery Android App With Glide
    Chike Mgbemena
  • Android O: How to Use Notification Channels
    Android SDK
    How to Make Calls and Use SMS in Android Apps
    Chike Mgbemena
  • Android O: How to Use Notification Channels
    Android SDK
    Get Started With RxJava 2 for Android
    Jessica Thornsby