【Kotlin】Notificationを出す

Notification(通知)を出して通知ドロワーに通知する機能を作ってみた。

以下のようにAndroid12の端末で動かせたのでご参考までに共有します。

通知を出すと、音量をオフにしていても「ピコーン!」と音がするので、何かお知らせする時には便利だ。

コードを紹介していきます。

API26以上の場合、NotificationChannelを作成する必要がある。

    private val channelId = "hoge"    
    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 = "a"
            val descriptionText = "b"
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(channelId, name, importance).apply {
                description = descriptionText
            }
            // Register the channel with the system
            val notificationManager: NotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

チャネルのIDや名前はなぜ設定する必要があるのか分からないが、適当に設定しても通知は出せたので気にしないことにする。

次に通知を出すところ。

    private fun showNotification(){

        createNotificationChannel()

        // タップ時に起動する画面を設定
        val intent = Intent(this, MainActivity::class.java)

        //既存のアクティビティを起動する
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)

        //既存のアクティビティを消して、新しくアクティビティを作成する
//        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)

        val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)

        val builder = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(android.R.drawable.btn_star)
            .setContentTitle("落下しましたよ!!!")
            .setContentText("スマホが落下したようです!!!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)

        val notificationManagerCompat = NotificationManagerCompat.from(this)
        notificationManagerCompat.notify(R.string.app_name, builder.build())
    }

通知を出すだけなら、インテントの設定は必要ない。

私の場合は、通知のタップをした時に起動中の画面に遷移したかったので、以下の設定をした。

  • インテントを作成
  • 起動中のActivity画面に遷移するようにフラグでSINGLE_TOPを指定
  • pendingIntentにインテントをセット
  • pendingintentをビルダーに設定

通知を出すだけなら簡単では?と思っていたが意外と難しかった。

つまづいた点は以下の通り。

  • 通知チャネルを作成しておらず通知が出ない
  • チャネルIDに何を設定して良いか分からない。
  • 通知をタップしたときに、Acitivityが再起動してしまう。
  • 通知をタップしたときに、起動中のAcitivityに遷移する方法が分からない。

1日がかりでStackOverflowを調べて解決した。