UnityでAndroid O向けに通知をする
概要
Android O では通知にChannel(チャンネル)という概念が導入されています。
Android O というのはAndroid8系の事で、APIバージョン26でAndroidManifestで言う所のtargetSdkVersion=26の事です。
で、Channelというのは通知をグルーピングして設定を変えたりできる類のものなのですが、Android O ではこの新機能のChannelを使う事が必須になっています。
使わない結果は↓の通りです。 チャンネルが無いよ(No Channel found)ってエラーが出ます。
07-08 13:28:25.682 1152-2944/? E/NotificationService: No Channel found for pkg=com.XXXXX.XXXXXXX, channelId=null, id=560, tag=null, opPkg=com.XXXXXX.XXXXXX, callingUid=10219, userId=0, incomingUserId=0, notificationUid=10219, notification=Notification(channel=null pri=0 contentView=null vibrate=[250,500,250,500] sound=android.resource://com.XXXXXX.XXXXXX/2131034112 defaults=0x4 flags=0x11 color=0x00000000 vis=PRIVATE)
当然Unityでも通知はAndroidの機能を使っていますので影響がありますので、既存アプリで通知機能があるアプリは更新が必要です。
対応案
案1:targetSdkVersionを25以下にする
急場はしのげるかもしれませんが、2018年の後半にはtargetSdkVersion=26以上がアプリの更新に必要となりますので、おすすめできません。 www.telemarks.co.jp
案2:自前で実装する
Androidのネイティブ処理詳しい方はどうぞ。 公式にサンプルコードがあります。
Notifications Overview | Android Developers
案3:Assetを使う
AssetStoreで通知(Notification)で検索すると、Assetがけっこうな数ヒットします。 Unity Asset Store - The Best Assets for Game Making
ここで気をつけなければいけないのが、「Android Oに対応してる」「Channelに対応している」と明記されているかどうかです。
こんな感じで書いてあれば多分大丈夫。更新が2017年の8月より昔のもの(まだAndroid Oが出ていない)や、明記されてないものは動かない可能性が高いです。
今回はこれを使ってみましたが、どれもそんなに変わらないと思います。
Android Local Notification Plugin - Asset Store
実装例
初期処理
private const string ANDROID_CHANNEL_ID = "channel1"; void Start(){ #if UNITY_EDITOR // nothing #elif UNITY_IOS #elif UNITY_ANDROID LocalNotificationUnity.CreateChannel(ANDROID_CHANNEL_ID, Define.APP_TITLE, Define.APP_TITLE, NotificationImportance.HIGH, true, true, "soundName", NotificationSoundContentType.UNKNOWN); #endif }
割と適当ですが、こんな感じで最初に起動する処理のStart() あたりでChannelを作ってあげましょう。 Channelを複数作って〜という事であればもっと複雑になりますが、とりあえず通知したいだけならこれで十分。 通知の時の音とかもこのタイミングで指定するようです。
通知処理
public static void SetAndroidLocalNotification(int id, int sec, string body){ #if UNITY_EDITOR Debug.Log("localnotify " + body); #elif UNITY_ANDROID DateTime now = DateTime.Now; TimeSpan secTS = new TimeSpan(0, 0, sec); LocalNotificationUnity.SendNotification(ANDROID_CHANNEL_ID, Define.APP_TITLE, body, now.Add(secTS), id); #endif }
このAssetはDatetimeを引数に取るタイプだったので、使いやすいようにラップする関数を適当に作ります。 通知するChanelも一緒に指定しますが、今回は1Channelしかないので固定値でOK。
つぶやき
- iOSはUnityの組み込み処理で通知ができるのになぜAndroidは無いのか
- このAssetは全部キャンセル処理がなぜか無かったです、、、
- Channel必須にしなくてもいいのになぁ、、、