⛩️

Flutterで緊急な通知を送りたい!

2023/12/31に公開

はじめに

大事な通知を送りたい時ってありませんか? 地震速報だったりSOSを伝えるためだったり。そんな時は普段使っている通知の設定を少し変えるだけでこれを実現することができます。
結論から述べると
iosでは重大な通知(Critical alerts)の設定を有効化
AndroidではIMPORTANCE_HIGHと設定します。
(後ほどそれぞれ詳しく解説します)

重大な通知(Critical alerts)とは?

重大な通知は、端末がマナーモードやおやすみモードの時でも、最大音量で通知音を鳴動させる通知です。

申請方法

重大な通知には、Apple が発行した特別な資格が必要です。
重大な通知が必要な理由を伝え審査を経て許可されるみたい。

Critical alerts require a special entitlement issued by Apple.

https://developer.apple.com/documentation/usernotifications/unauthorizationoptions/2963120-criticalalert
私も実際に申請したことはありません。いつかやりたい。以下で詳しく解説してくれています!
https://zenn.dev/u_motion_tech/articles/ios-critical-alert#appleへの申請と審査

重大な通知音の変更方法

そもそも変更していいの?

Appleコミュニティーによると公的緊急事態や政府の警報を除き変更することは可能とのこと
ただ私が聞いたケースとして、SOSの音が公式から変更されアプリ側で再設定したことがあるらしいので柔軟に対応していきましょう。

If you're talking about critical alerts in terms of public emergencies, government alerts, etc., the tone for that can't be changed.

https://discussions.apple.com/thread/254126612?answerId=257750355022&sortBy=best#257750355022
まあ実際私は変更したアプリを作成していますし、何よりパラメータが用意されているので今回は活用させていただきます!

実践

iosの通知音変更はFCMのapns>aps>soundのnameに設定した音声ファイル名を記載することで変更することができます。

XCodeにwavファイルを設定する

今回はsos.wavと言う音声ファイルを用意しました。

  apns: {
      payload: {
        alert: {
          title: (ここにtitle)
          body: (ここにbody)
        },
        aps: {
          contentAvailable: true,
          badge: 1,
          sound: {
            critical: true,
            name: sos.wav,  //ここに設定した音声ファイル名
          },
        },
      },
    },

https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#ApnsConfig

Androidの重大な通知

Androidではiosのような重大な通知はありませんが、importance(優先度)を通知に設定することができます。優先度については以下の通り。

優先度が高いほど他の優先度が低い通知よりも優先的に表示されます。
https://developer.android.com/training/notify-user/channels?hl=ja#importance

Androidの通知音を変更する

{
 "priority" : "high", //優先度を設定する
 "notification" : {
     "body" : (ここにbody),
     "title": (ここにtitle),
     "sound": "sos.wav" //私の環境だと動作せず
 }
}

MainActivity.kt

   private fun createNotification() {
        val sound = "sos" //ここに設定したファイル名を記載する
        val resId = resources.getIdentifier(sound, "raw", packageName)
        val uri = Uri.parse("android.resource://${packageName}/${resId}")
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "ChannelName"
            val descriptionText = "description"
            val importance = NotificationManager.IMPORTANCE_HIGH
            val audioAttributes = AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .build()

            val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
                description = descriptionText
                setShowBadge(true)
                enableVibration(true)
                setBypassDnd(true)
                setSound(uri, audioAttributes)
            }
            val notificationManager: NotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }


https://stackoverflow.com/questions/54002617/custom-sound-push-notification-does-not-work-flutter/54003722#54003722
https://dev.classmethod.jp/articles/change-android-notification-sound/

おまけ Androidの通知を柔軟に変更したい(検証中)

こちらの検証を長らくやっていたため記事を書くのが遅くなってしまいました🙏
ただ結論から言うとまだできてません
FCMからdataを渡すと言うことはすでにできていますが、
簡潔に言うとバックグラウンド時はonMessageReceivedではなくシステムトレイに一時的にdataを渡さされるためなんですが、そこから取り出せず止まってしまっています。
もう少しintent.extras(システムトレイからdataを取り出すために使用する)について深掘りして真相に迫りたいと思います。

参考記事(もし興味があれば下記を参考にしてみてください)
https://stackoverflow.com/questions/74565141/how-do-i-send-a-high-priority-inbox-style-notification-on-android-using-fcm
https://qiita.com/nk5jp/items/841096efa0903cb72d58#11-フォアグラウンドにいる場合firebasemessagingservice
https://github.com/firebase/quickstart-android/issues/96
https://stackoverflow.com/questions/53780253/getintent-getextras-returns-null-data-on-notification-click-fcm

参考

緊急通知について
https://www.unlockboot.com/enable-disable-critical-alerts-ios-12/
FCMについて 
https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#AndroidConfig

Discussion