[Kotlin] Androidにおける通知の送信と通知をタップしたときの処理

2018年4月27日(更新: 2018年4月27日)

Android通知Notification)を送信する処理と、その通知をタップしてアクティビティを開く処理の実装方法についてです。

通知はホーム起動時や画面を上からスワイプしたときに一覧で表示されます。

Androidの通知の送信例

通知のタップで新しいアクティビティを開く場合、その通知を送った画面を親アクティビティ(戻れる画面)として設定することがあると思いますので、その実装に関しても紹介します。

通知を送るサンプル

サンプルアプリのコードです。

ボタンを押して通知を送信し、通知をタップした時にアクティビティを開く処理を行います。

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val layout = LinearLayout(this)
        setContentView(layout)

        val button = Button(this)
        button.setText("実行")
        layout.addView(button)

        button.setOnClickListener {
            
            // 通知の設定
            val builder = Notification.Builder(this).apply {
                setSmallIcon(R.drawable.notification_template_icon_bg)// 必須
                setContentTitle("Title")
                setContentText("This is a notification")
                setAutoCancel(true)
                setDefaults(Notification.DEFAULT_ALL)
            }

            // 親となるアクティビティを指定 マニフェストに追記が必要
            val stackBuilder = TaskStackBuilder.create(this)
            stackBuilder.addParentStack(NewActivity::class.java)

            // 表示するアクティビティ
            stackBuilder.addNextIntent(Intent(this, NewActivity::class.java))

            // 通知をタップした時に開くインテントを設定
            val pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
            builder.setContentIntent(pendingIntent)

            // 通知を送信
            val notificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.notify(0, builder.build())
        }
    }
}

// 通知をタップした際に開くアクティビティ
class NewActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Toast.makeText(this, "New Activity", Toast.LENGTH_LONG).show()
    }
}

マニフェスト(AndroidManifest.xml)には、新しく開くアクティビティの親を android:parentActivityName のプロパティで以下のように設定します。

これを書かないと戻るボタンで元のアクティビティに戻れないため注意して下さい。

...

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity
    android:name=".NewActivity"
    android:parentActivityName=".MainActivity"></activity>

...

実行すると、まず通知を送るボタンがある画面が表示されます。

通知を送るサンプルアプリのメインアクティビティ

ボタンを押すと通知が届きます。

端末に届いた通知の例

通知をタップすると、新しい画面が開き、同時に Toast でメッセージが表示されます。

通知をタップして開かれたアクティビティ

端末のバックボタンやアプリ左上の矢印をタップすると、元の画面に戻ります。

サンプルプログラムの詳細

今回、通知の送信には Notification.Builder を利用しています。

Notification.Builder は API level 26Android 8.0) 以降では非推奨ですが、そこまでアップデートできる端末が今のところ少ないため、引き続き利用する機会が多いかも知れません。新しい実装は Notification Channel を利用するようです。

通知にはアイコンとタイトル、本文が必須です。これらは以下のメソッドで設定します。

setSmallIcon(R.drawable.notification_template_icon_bg)
setContentTitle("Title")
setContentText("This is a notification")

通知をタップした際に、通知を一覧から削除するには、以下のメソッドを設定します

setAutoCancel(true)

通知が届いた時に、端末に発音や振動を行わせるには、以下のメソッドを設定します。

setDefaults(Notification.DEFAULT_ALL)

通知をタップした時に開くアクティビティを指定するには、メソッド setContentIntent に Intent または PendingIntent を渡します

今回はアクティビティの階層を維持するために TaskStackBuilder を利用して PendingIntent を作成しています。

TaskStackBuilder のメソッド addParentStack は、指定したアクティビティにマニフェストで親として指定されたアクティビティを親とします。したがって、以下の指定によって NewActivity の親である MainActivity が親アクティビティとなります。

addParentStack(NewActivity::class.java)

そして addNextIntent によって、その子となるアクティビティを指定します。このメソッドによって複数のアクティビティを階層的に指定することができます。

開発中に、上記の通りに実装したにも関わらず親アクティビティに戻れない不具合が発生する場合があります。

筆者自身が嵌ったのですが、アプリの再インストールを試してみたところ直りました。

Android – Build a notification, TaskStackBuilder.addParentStack not working – Stack Overflow

以上が、KotlinによるAndroid端末の通知の送信と、通知をタップしたときの処理の実装方法です。

参考

通知  |  Android Developers

TaskStackBuilder  |  Android Developers

コメントを残す

メールアドレスが公開されることはありません。