通知が届かないので Android NotificationChannel の使い方を調べてみた

# NotificationChannel とは？
2018年夏～秋にかけての話になりますが、ビルドする Android SDK の APIレベルを26(Android8)に上げたところ通知が届かなくなりました。
よくよく調べてみると Android8(APIレベル26)以降、通知を表示するにはNotificationChannel を指定しなければならなくなりました。通知を実装していく上で NotificationChannel の実装・検証の過程で躓いたり気づいたことがありましたので、こちらにまとめます。

# NotificationChannel 作成時の注意点

## 作成タイミング
通知を使用するのなら NotificationChannel はアプリを起動した直後に作成すべきです。
なぜなら通知はユーザーが能動的に呼び出すものではありません。よってアプリを一度でも起動したら、端末の「設定」から NotificationChannel の設定を変更できるようになるべきです。初回起動直後に作成するようにしましょう。

## デフォルトのID
デフォルトのID "miscellaneous" が存在していますが、このIDを指定して createChannel をしても作ることはできません。このチャンネルは APIレベル26未満のSDKでビルドされたプログラムで通知を実装したときに使用されるチャンネルです。APIレベル26以降でこちらのIDを指定しても通知は届きません。

## 初回作成時のみしか設定できない項目
NotificationChannel には初回作成時のみしか設定できない項目が存在しています。たとえ deleteChannel して createChannel を行なっても、**アプリを消して再インストールする または アプリのストレージのデータを削除する** をしない限り変更できません。なのでアプリをリリースする際には、リリース前に NotificationChannel の設定を決めておく必要があります。

| NotificationChannel のメソッド | このメソッドで変更可能か？ |
|:----|:----|
| [void enableLights(boolean lights)](https://developer.android.com/reference/android/app/NotificationChannel.html#enableLights(boolean)) | 設定メニューで変更可能 <br> 初回作成時のみ有効 |
| [void enableVibration(boolean vibration)](https://developer.android.com/reference/android/app/NotificationChannel.html#enableVibration(boolean)) | 設定メニューで変更可能 <br> 初回作成時のみ有効 |
| [void setAllowBubbles (boolean allowBubbles)](https://developer.android.com/reference/android/app/NotificationChannel.html#setAllowBubbles(boolean)) | 不可 <br> ※API レベル29～ 未検証 |
| [void setDescription(String description)](https://developer.android.com/reference/android/app/NotificationChannel.html#setDescription(java.lang.String)) | 可能 |
| [void setBypassDnd(boolean bypassDnd)](https://developer.android.com/reference/android/app/NotificationChannel.html#setBypassDnd(boolean)) | アプリから呼びだしても効果なし |
| [void setGroup(String groupId)](https://developer.android.com/reference/android/app/NotificationChannel.html#setGroup(java.lang.String)) | 不可 |
| [void setImportance(int importance)](https://developer.android.com/reference/android/app/NotificationChannel.html#setImportance(int)) | 設定メニューで変更可能 <br> 初回作成時のみ有効 |
| [void setLightColor(int argb)](https://developer.android.com/reference/android/app/NotificationChannel.html#setLightColor(int)) | 不可 |
| [void setLockscreenVisibility(int lockscreenVisibility)](https://developer.android.com/reference/android/app/NotificationChannel.html#setLockscreenVisibility(int)) | アプリから呼びだしても効果なし <br> 初回チャンネル作成時に、その時の端末の「ロック画面の通知設定」からコピーされ、チャンネルの設定メニューで変更可能となる <br> 「ロック画面の通知設定」と「アプリの通知設定」から、よりセキュリティ的に強い状態で通知が表示される |
| [void setName(CharSequence name)](https://developer.android.com/reference/android/app/NotificationChannel.html#setName(java.lang.CharSequence)) | 可能 |
| [void setShowBadge(boolean showBadge)](https://developer.android.com/reference/android/app/NotificationChannel.html#setShowBadge(boolean)) | 設定メニューで変更可能 <br> 初回作成時のみ有効 |
| [void setSound(Uri sound, AudioAttributes audioAttributes)](https://developer.android.com/reference/android/app/NotificationChannel.html#setSound(android.net.Uri,%20android.media.AudioAttributes)) | 設定メニューで変更可能 <br> 初回作成時のみ有効 <br> アプリ内のサウンドを指定するように実装し、設定メニューから別のサウンドに変更すると、ここで設定したリソースへ戻し方がわからない。戻せない？ |
| [void setVibrationPattern(long[] vibrationPattern)](https://developer.android.com/reference/android/app/NotificationChannel.html#setVibrationPattern(long[])) | 不可 |

# 通知実装時の注意点

## 通知時に設定しても NotificationChannel の設定が使用される項目
* サウンド
* ライト
* 振動
* ロック画面での表示(visibility)

Android8未満に対応する場合はこれらを設定して通知を呼びだすと、Android8以降の端末では NotificationChannel の設定が反映され、Android8未満の端末では通知時の設定が反映されます。

# 動作検証時は端末設定を確認しよう
* 通知に関する実装の検証を行なう場合は、アプリの「通知設定」だけではなく端末の「設定」の「通知」を確認して、実装しようとしている機能がオンになっていることを確認しましょう。また通知ランプはそもそも通知用のLEDを搭載していない端末もあるので、検証している端末が機能を満たしているか確認しましょう。
* ロック画面での通知表示を確認するには、端末のロック解除にセキュリティをかけて確認する必要があります。セキュリティをかけていない状態では「すべての内容が表示される」という状態になります。