I've been struggling with the new NotificationChannels
which is introduced in API 26 and up.
I'm developing an app with an option to choose whether to be notified in four cases:
In all cases, my app notify with sound and vibrate whatever I choose.
My code is:
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);
Also, I change CHANNEL_ID
every time I run the app, so it gets a fresh Channel ID every time just for testing until I find a solution.
Of course, it works fine with API less than 26.
Thank you, guys!
Thank you all guys,
I managed to solve it by simply creating a NotificationCompat.Builder
and NotificationChannel
for each and every case, and notify each Builder
when its condition is met.
I don't know if this is the best practice, but I'll try to optimize the code later, if anyone has an opinion on that feel free. But it worked so fine now.
Here's my code:
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());
}
i found this in the documentation. May be it will help you :
On Android 8.0 (API level 26) and above, importance of a notification is determined by the importance of the channel the notification was posted to. Users can change the importance of a notification channel in the system settings (figure 12). On Android 7.1 (API level 25) and below, importance of each notification is determined by the notification's priority.
And also :
Android O introduces notification channels to provide a unified system to help users manage notifications. When you target Android O, you must implement one or more notification channels to display notifications to your users. If you don't target Android O, your apps behave the same as they do on Android 7.0 when running on Android O devices.
And finally :
- Individual notifications must now be put in a specific channel.
- Users can now turn off notifications per channel, instead of turning off all notifications from an app.
- Apps with active notifications display a notification "badge" on top of their app icon on the home/launcher screen.
- Users can now snooze a notification from the drawer. You can set an automatic timeout for a notification.
- Some APIs regarding notification behaviors were moved from Notification to NotificationChannel. For example, use NotificationChannel.setImportance() instead of NotificationCompat.Builder.setPriority() for Android 8.0 and higher.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With