私は、API 26以降で導入された新しいNotificationChannels
と格闘しています。
次の4つの場合に通知するかどうかを選択するオプションを備えたアプリを開発しています。
すべての場合において、私のアプリは音で通知し、選択したものを振動させます。
私のコードは:
NotificationCompat.Builder builder;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new NotificationCompat.Builder(context, CHANNEL_ID);
int importance;
NotificationChannel channel;
//Boolean for choosing Sound
if(sound) {
importance = NotificationManager.IMPORTANCE_DEFAULT;
} else {
importance = NotificationManager.IMPORTANCE_LOW;
}
channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance);
channel.setDescription(CHANNEL_DESC);
//Boolean for choosing Vibrate
if(vibrate) {
channel.enableVibration(true);
} else {
channel.enableVibration(false);
}
notificationManager.createNotificationChannel(channel);
} else {
builder = new NotificationCompat.Builder(context);
}
if(sound && vibrate) {
//Sound and Vibrate
builder.setDefaults(Notification.DEFAULT_ALL);
} else if(sound && !vibrate) {
//Sound
builder.setDefaults(Notification.DEFAULT_SOUND);
} else if(!sound && vibrate) {
//Vibrate
builder.setDefaults(Notification.DEFAULT_VIBRATE);
} else if(!sound && !vibrate) {
//None
//Do nothing! just notification with no sound or vibration
}
builder.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setOnlyAlertOnce(false)
.setPriority(Notification.PRIORITY_MAX);
また、CHANNEL_ID
アプリを実行するたびに、テストのためだけに毎回新しいチャンネルIDを取得して解決策を見つけます。
もちろん、26未満のAPIでは問題なく動作します。
君たちありがとう!
私はこれをドキュメントで見つけました。それはあなたを助けるかもしれません:
Android 8.0(APIレベル26)以降では、通知の重要度は、通知が投稿されたチャネルの重要度によって決まります。ユーザーは、システム設定で通知チャネルの重要度を変更できます(図12)。 Android 7.1(APIレベル25)以下では、各通知の重要度は通知の優先度によって決まります。
そしてまた:
Android Oでは、ユーザーが通知を管理するのに役立つ統合システムを提供する通知チャネルが導入されています。 Android Oをターゲットとする場合、ユーザーに通知を表示するには、1つ以上の通知チャネルを実装する必要があります。 Android Oをターゲットにしていない場合、アプリはAndroid Oデバイスで実行した場合のAndroid 7.0と同じように動作します。
そして最後に :
- 個々の通知は特定のチャネルに配置する必要があります。
- ユーザーは、アプリからのすべての通知をオフにする代わりに、チャネルごとの通知をオフにできるようになりました。
- 通知がアクティブなアプリは、ホーム/ランチャー画面のアプリアイコンの上に通知「バッジ」を表示します。
- ユーザーは引き出しから通知をスヌーズできるようになりました。通知の自動タイムアウトを設定できます。
- 通知動作に関する一部のAPIは、NotificationからNotificationChannelに移動されました。たとえば、Android 8.0以降では、NotificationCompat.Builder.setPriority()の代わりにNotificationChannel.setImportance()を使用します。
みんなありがとう、
ケースごとにNotificationCompat.Builder
とNotificationChannel
を作成するだけで解決でき、条件が満たされたときに各Builder
に通知します。
これがベストプラクティスかどうかはわかりませんが、誰かが自由に感じているという意見があれば、後でコードを最適化しようとします。しかし、それは今とてもうまくいきました。
これが私のコードです:
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationCompat.Builder builder_all, builder_sound, builder_vibrate, builder_none;
NotificationChannel channel_all = new NotificationChannel(CHANNEL_ID_ALL, CHANNEL_NAME_ALL, NotificationManager.IMPORTANCE_HIGH);
channel_all.enableVibration(true);
notificationManager.createNotificationChannel(channel_all);
NotificationChannel channel_sound = new NotificationChannel(CHANNEL_ID_SOUND, CHANNEL_NAME_SOUND, NotificationManager.IMPORTANCE_HIGH);
channel_sound.enableVibration(false);
notificationManager.createNotificationChannel(channel_sound);
NotificationChannel channel_vibrate = new NotificationChannel(CHANNEL_ID_VIBRATE, CHANNEL_NAME_VIBRATE, NotificationManager.IMPORTANCE_HIGH);
channel_vibrate.setSound(null, null);
channel_vibrate.enableVibration(true);
notificationManager.createNotificationChannel(channel_vibrate);
NotificationChannel channel_none = new NotificationChannel(CHANNEL_ID_NONE, CHANNEL_NAME_NONE, NotificationManager.IMPORTANCE_HIGH);
channel_none.setSound(null, null);
channel_none.enableVibration(false);
notificationManager.createNotificationChannel(channel_none);
//Boolean for Sound or Vibrate are chosen
if(sound && vibrate) {
builder_all = new NotificationCompat.Builder(context, CHANNEL_ID_ALL);
builder_all.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setOnlyAlertOnce(false);
switch (transition) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
builder_all.setSmallIcon(R.drawable.ic_entered_white);
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
builder_all.setSmallIcon(R.drawable.ic_left_white);
break;
}
notificationManager.notify(notificationID, builder_all.build());
} else if(sound && !vibrate) {
builder_sound = new NotificationCompat.Builder(context, CHANNEL_ID_SOUND);
builder_sound.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setOnlyAlertOnce(false);
switch (transition) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
builder_sound.setSmallIcon(R.drawable.ic_entered_white);
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
builder_sound.setSmallIcon(R.drawable.ic_left_white);
break;
}
notificationManager.notify(notificationID, builder_sound.build());
} else if(!sound && vibrate) {
builder_vibrate = new NotificationCompat.Builder(context, CHANNEL_ID_VIBRATE);
builder_vibrate.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setOnlyAlertOnce(false);
switch (transition) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
builder_vibrate.setSmallIcon(R.drawable.ic_entered_white);
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
builder_vibrate.setSmallIcon(R.drawable.ic_left_white);
break;
}
notificationManager.notify(notificationID, builder_vibrate.build());
} else if(!sound && !vibrate) {
builder_none = new NotificationCompat.Builder(context, CHANNEL_ID_NONE);
builder_none.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setOnlyAlertOnce(false);
switch (transition) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
builder_none.setSmallIcon(R.drawable.ic_entered_white);
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
builder_none.setSmallIcon(R.drawable.ic_left_white);
break;
}
notificationManager.notify(notificationID, builder_none.build());
}
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
if(sound && vibrate) {
//Sound and Vibrate
builder.setDefaults(Notification.DEFAULT_ALL);
} else if(sound && !vibrate) {
//Sound
builder.setDefaults(Notification.DEFAULT_SOUND);
} else if(!sound && vibrate) {
//Vibrate
builder.setDefaults(Notification.DEFAULT_VIBRATE);
} else if(!sound && !vibrate) {
//None
//Do nothing! just notification with no sound or vibration
}
builder.setSmallIcon(R.drawable.ic_logo)
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setOnlyAlertOnce(false)
.setPriority(Notification.PRIORITY_MAX);
switch (transition) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
builder.setSmallIcon(R.drawable.ic_entered_white);
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
builder.setSmallIcon(R.drawable.ic_left_white);
break;
}
notificationManager.notify(notificationID, builder.build());
}
サウンドとバイブレーションのブール値がアプリの設定からのものである場合は、アプリからそれらを削除し、代わりにユーザーをチャネル設定に送る必要があることに注意してください。
「通知チャネルを作成した後、プログラムで通知チャネルの視覚的および聴覚的動作を変更することはできません。システム設定からチャネル動作を変更できるのはユーザーだけです。これらの通知設定にユーザーが簡単にアクセスできるようにするには、アイテムをこれらのシステム設定を開くアプリの設定UI。」
https://developer.Android.com/training/notify-user/channels#UpdateChannel