【Android】ローカルプッシュ通知についてまとめた

アイキャッチ_プッシュ通知Androidアプリ開発
サバ缶
サバ缶

どうもこんにちは!
サバ缶(@tech_begin)です。

とある業務で、ローカルプッシュ通知を実装しました。

個人的に初めてのことで、若干時間がかかった部分でしたので備忘録としてまとめます。

ローカルプッシュ通知とは?

一般的なプッシュ通知は、「今日のおすすめ動画はこちら!」とか見慣れたアレのことです。

プッシュ通知について

プッシュ通知を受け取るスマホの「デバイス識別番号」をサーバ側に登録します。

そして、その識別番号を使って、端末を特定し、条件にあったユーザにプッシュ通知を送ることが可能です。

例えば、「●●さんからメッセージが来ています!」とかですね。

それらは、サーバが動作して、各スマホに送信しています。

しかし、ローカルプッシュ通知はスマホ内で、好きなタイミングでプッシュ通知を送ることが出来ます。

Android でのローカルプッシュ通知実装

必要最低限の実装は、以下をご参照いただければ可能です。

サバ缶
サバ缶

そのまんま載っけます!

ちなみに、言語はKotlinです。

// ①インテントの作成
val intent = Intent(this, MainActivity::class.java).apply {
  flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)

// ②通知の準備
val channelId = "NOTIFICATION_LOCAL"
val builder = NotificationCompat.Builder(this, channelId).apply {
  setSmallIcon(R.drawable.smallIcon)
  setContentTitle("通知タイトル")
  setContentText("通知内容")
  setContentIntent(pendingIntent)
  priority = NotificationCompat.PRIORITY_HIGH
}

// ③チャネルの設定
// Android8(API26)以上の場合、チャネルに登録する
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  val name = "通知名サンプル"
  val description = "通知説明文サンプル"
  val importance = NotificationManager.IMPORTANCE_HIGH
  val channel = NotificationChannel(channelId, name, importance).apply {
    this.description = description
  }
  // システムにチャネルを登録する
  val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager manager.createNotificationChannel(channel)
}

// ④ローカルプッシュ通知を送信する
with(NotificationManagerCompat.from(this)) {
  notify(12345, builder.build())
}

コードの内容を解説

①インテントの作成

val intent = Intent(this, MainActivity::class.java).apply {
  flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)

ローカルプッシュ通知をタップした時に、遷移するための処理を記述します。

通常のIntentではなく「PendingIntent」というものを使用します。

PendingIntentは、外部アプリ(実装したアプリ以外のもの)に与えることで、他のアプリも自分自身のアプリのように動作させることができます。

今回で言えば、ローカルプッシュ通知なので、Androidのホームアプリとの連携という意味になります。

②通知の準備

val channelId = "NOTIFICATION_LOCAL"
val builder = NotificationCompat.Builder(this, channelId).apply {
  setSmallIcon(R.drawable.smallIcon)
  setContentTitle("通知タイトル")
  setContentText("通知内容")
  setContentIntent(pendingIntent)
  priority = NotificationCompat.PRIORITY_HIGH
}

NotificationCompatのビルダーを使って、文言やアイコンなどを設定します。
priority は、通知の優先度を設定するものです。

詳細は、公式ドキュメントをご参照ください。

通知を作成する  |  Views  |  Android Developers

③チャネルの設定

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  val name = "通知名サンプル"
  val description = "通知説明文サンプル"
  val importance = NotificationManager.IMPORTANCE_HIGH
  val channel = NotificationChannel(channelId, name, importance).apply {
    this.description = description
  }
  // システムにチャネルを登録する
  val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager manager.createNotificationChannel(channel)
}

Android8以上では、「アプリの通知チャネル」という機能が搭載されています。

そのシステム側への登録が必要になります。

アプリの通知チャネルとは?

ユーザが細かい通知の設定をできる機能です。

メッセージの通知はOFFにして、通話の通知はONにしよう…のように各通知を切り替えることできます。

ちなみに、Android 13以降では通知のリクエストを行う必要があります。
Android 12までは、デフォルトで権限がONになっていたものが、OFFになるようです。

通知に関する実行時の権限  |  Views  |  Android Developers

④ローカルプッシュ通知を送信

with(NotificationManagerCompat.from(this)) {
  notify(12345, builder.build())
}

あとは、ビルダーを使ってプッシュ通知を送信します。

「12345」というのは、チャネルの番号です。任意で書き換えてください。

【補足】Kotlinの構文について

applyを使うと便利です!

一時変数の記載が不要になるので、コードがとても簡略化できます。

Kotlinでスコープ関数「apply」を使えば、一時変数を書かなくてすむの巻 - Qiita
こんにちは。Kotlinを学びだすと、「なんだコレは?コレを使って何がオイシいのか?」と、その存在意義を疑いたくなるような感覚に陥っている最中の私です。特に、**スコープ関数の「apply」**…

【補足】長文の通知をスライドして表示させる

あれ?
さっきのコードだと、通知が全文表示されないです……。

そんな時は、以下の処理を加えると対応可能です。

.setStyle( NotificationCompat.BigTextStyle()
  .setBigContentTitle("スライドして全文表示した時のタイトル")
  .bigText("全文表示した時の全文(基本的にはsetContentsと同じ文章)")
)

参考記事

通知を作成する  |  Views  |  Android Developers
PendingIntent  |  Android Developers
日々の記録
SNS は無限に時間を溶かすのでやらないことにした
Androidで表示できる通知まとめ | DevelopersIO
Notificationを勉強し直す | Simple is Best
OJI のブログ
タイトルとURLをコピーしました