💈

【Android】Notification通知をKotlinで実装してみました。

2023/11/16に公開

最初に

アンドロイドのNotification通知機能について調べて、直接実装してみました。

Notificationの実装流れ

最も基本的なノーティフィケーション(お知らせ)の流れです。
デフォルトでは、ノーティフィケーションは次のようなメインロジックで構成されています。

  1. 通知コンテンツ設定
    (NotificationBuilder、PendingIntentを使用)
  2. チャネルを作成して重要度を設定する
  3. 通知表示

通知のコンテンツを設定

最初に、NotificationCompat.Builder オブジェクトを使用して、通知のコンテンツとチャネルを設定する必要があります。

setSmallIcon()

設定される小さなアイコン。これは、ユーザーに表示されるコンテンツのうち、唯一必須な要素です。

setContentTitle()

設定されるタイトル。

setContentText()

設定される本文テキスト。

setPriority()

で設定される通知の優先度。Android 7.1 以下では、優先度は、通知がユーザーの操作に割り込む度合いを表します(Android 8.0 以上では、チャネルの重要度を設定する必要があります。これについては次のセクションで説明します)。

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle(textTitle)
            .setContentText(textContent)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    

###その他の設定

  • setCategory
    Message、Call、Alarmなどのカテゴリを設定することができる。 (妨害禁止モードで通知を表示するときに使用する。)
  • setOngoing
    ユーザーが通知を消すことができない。
  • setAutoCancel
    通知をクリックすると通知が消える。
  • setUsesChronometer
    Timeの代わりにChronometerが表示される。
  • setTicker
    Status Barに一行で表示されるメッセージ。
  • setTimeoutAfter
    指定された時間後に通知が消える。

チャネルを作成して重要度を設定

Android 8.0 以上で通知を配信するには、NotificationChannel のインスタンスを createNotificationChannel() に渡すことにより、アプリの通知チャネルをシステムに登録しておく必要があります。したがって、次のコードは SDK_INT バージョンの条件によってブロックされます。

 private fun createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = getString(R.string.channel_name)
            val descriptionText = getString(R.string.channel_description)
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
                description = descriptionText
            }
            // Register the channel with the system
            val notificationManager: NotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

実装

@Singleton
class NormalNotificationManager @Inject constructor(
    @ApplicationContext
    private val context: Context
) {
    companion object {
        private const val CHANNEL_ID = "Test_Id"
        private const val CHANNEL_NAME = "Test_Chanel"
        private const val CHANNEL_DESCRIPTION = "Test_Notification"
    }

    private val manager by lazy { context.getSystemService(NotificationManager::class.java) }

    fun notify(message: Message) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel()
        }


        val notification = NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_Icon) // Icon
            .setContentTitle(message.title) // Title
            .setContentText(message.message) // Content
            .setPriority(NotificationCompat.PRIORITY_MAX) 
            .build()

        manager.notify(message.id, notification)
    }

    fun cancel(message: Message) {
        manager.cancel(message.id)
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel() {
        val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH).apply {
            description = CHANNEL_DESCRIPTION
        }

        manager.createNotificationChannel(channel)
    }
}

最後に

Androidでは様々なスタイルの通知を表示することができます。用途にあわせて適切なものを使うことで、より効果的に利用者に通知を送ることが出来ます。

Discussion