android: 通知をAPI=26に対応させるには

Android 8.0 (APIレベル26)から、通知のチャンネル指定が必要になりました。

この記事では、従来のNotification処理に、チャンネルを追加する方法を説明します。

res/values/strings.xml

チャンネルIDとチャンネル名を定義します。

リソース名 "default_notification_channel_id" や、その値 "Information"は任意です。

リソース定義は必須ではなく、APIの引数に、文字列を直接書いてもいいです。

<string name="default_notification_channel_id" translatable="false">Information</string>
<string name="default_notification_channel_name">Information</string>
Code language: HTML, XML (xml)

MyApplicationクラスでチャンネル登録

通知をする前に、チャンネル登録します。一回だけチャンネル登録すればいいので、MyApplicationクラスで呼ぶことにします。なお、チャンネル登録は何回呼んでも問題ないようです。

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        ...
        NotificationHelper.createNotificationChannel(context);
Code language: PHP (php)
public class NotificationHelper {

    public static void createNotificationChannel(final Context appContext) {
        if (Build.VERSION.SDK_INT <= 25) {
            return;
        }

        final String channel_id = appContext.getString(R.string.default_notification_channel_id);
        final String channel_name = appContext.getString(R.string.default_notification_channel_name);
        final NotificationChannel notificationChannel = new NotificationChannel(channel_id, channel_name, NotificationManager.IMPORTANCE_LOW);

        NotificationManager notificationManager = (NotificationManager) appContext.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(notificationChannel);

    Code language: PHP (php)

通知

従来のNotification処理が次のようなものだとします。

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        ...

        Notification notification = notificationBuild(
            title,
            messageBody,
            pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, notification);
    }

    private Notification notificationBuild(
        String title,
        String messageBody,
        PendingIntent pendingIntent
    ) {
        NotificationCompat.Builder notificationBuilder = 
            new NotificationCompat.Builder(this)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent);

        return notificationBuilder.build();
    }Code language: JavaScript (javascript)

notificationBuildメソッドを、SDK_INT <= 25、SDK_INT >= 26の場合に分けます。

private Notification notificationBuild(
    String title,
    String messageBody,
    PendingIntent pendingIntent
) {
    if (Build.VERSION.SDK_INT <= 25) {
        notificationBuild_before25(title, messageBody, pendingIntent);
    } else {
        notificationBuild_after26(title, messageBody, pendingIntent);
    }
}

private Notification notificationBuild_before25(
    String title,
    String messageBody,
    PendingIntent pendingIntent
) {
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle(title)
        .setContentText(messageBody)
        .setAutoCancel(true)
        .setContentIntent(pendingIntent);

    return notificationBuilder.build();
}

@RequiresApi(api = 26)
private Notification notificationBuild_after26(
    String title,
    String messageBody,
    PendingIntent pendingIntent
) {
    Notification.Builder notificationBuilder = new Notification.Builder(this)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle(title)
        .setContentText(messageBody)
        .setAutoCancel(true)
        .setChannelId(getString(R.string.default_notification_channel_id))
        .setContentIntent(pendingIntent);

    return notificationBuilder.build();
}Code language: JavaScript (javascript)

スクリーンショット

アプリ情報>通知。登録したチャンネル名「Information」が表示されていました。

アプリ情報>通知:チャンネル名「Information」

タイトルとURLをコピーしました