I get this message when trying to display a notification on Android O.
Use of stream types is deprecated for operations other than volume control
In Android O it's a must to use a NotificationChannel
and NotificationCompat.Builder
is deprecated (reference).
Below is a sample code :
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(mContext.getApplicationContext(), "notify_001");
Intent ii = new Intent(mContext.getApplicationContext(), RootActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, ii, 0);
NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
bigText.bigText(verseurl);
bigText.setBigContentTitle("Today's Bible Verse");
bigText.setSummaryText("Text in detail");
mBuilder.setContentIntent(pendingIntent);
mBuilder.setSmallIcon(R.mipmap.ic_launcher_round);
mBuilder.setContentTitle("Your Title");
mBuilder.setContentText("Your text");
mBuilder.setPriority(Notification.PRIORITY_MAX);
mBuilder.setStyle(bigText);
NotificationManager mNotificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("notify_001",
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
}
mNotificationManager.notify(0, mBuilder.build());
Per the comments on this Google+ post:
those [warnings] are currently expected when using
NotificationCompat
on Android O devices (NotificationCompat
always callssetSound()
even if you never pass in custom sound).until the Support Library changes their code to use the
AudioAttributes
version ofsetSound
, you'll always get that warning.
Therefore there's nothing that you can do about this warning. As per the notification channels guide, Android O deprecates setting a sound on an individual notification at all, instead having you set the sound on a notification channel used by all notifications of a particular type.
Starting with Android O, you are required to configure a NotificationChannel, and reference that channel when you attempt to display a notification.
private static final int NOTIFICATION_ID = 1;
private static final String NOTIFICATION_CHANNEL_ID = "my_notification_channel";
...
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_DEFAULT);
// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
notificationManager.createNotificationChannel(notificationChannel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setVibrate(new long[]{0, 100, 100, 100, 100, 100})
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Content Title")
.setContentText("Content Text");
notificationManager.notify(NOTIFICATION_ID, builder.build());
A couple of important notes:
NotificationChannel
override those specified in the actual Notification
. I know, its counter-intuitive. You should either move settings that will change into the Notification, or use a different NotificationChannel for each configuration.NotificationChannel
settings after you've passed it to createNotificationChannel()
. You can't even call deleteNotificationChannel()
and then try to re-add it. Using the ID of a deleted NotificationChannel
will resurrect it, and it will be just as immutable as when it was first created. It will continue to use the old settings until the app is uninstalled. So you had better be sure about your channel settings, and reinstall the app if you are playing around with those settings in order for them to take effect.All that @sky-kelsey has described is good, Just minor additions:
You should not register same channel every time if it has been already registered, so I have Utils class method that creates a channel for me:
public static final String NOTIFICATION_CHANNEL_ID_LOCATION = "notification_channel_location";
public static void registerLocationNotifChnnl(Context context) {
if (Build.VERSION.SDK_INT >= 26) {
NotificationManager mngr = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
if (mngr.getNotificationChannel(NOTIFICATION_CHANNEL_ID_LOCATION) != null) {
return;
}
//
NotificationChannel channel = new NotificationChannel(
NOTIFICATION_CHANNEL_ID_LOCATION,
context.getString(R.string.notification_chnnl_location),
NotificationManager.IMPORTANCE_LOW);
// Configure the notification channel.
channel.setDescription(context.getString(R.string.notification_chnnl_location_descr));
channel.enableLights(false);
channel.enableVibration(false);
mngr.createNotificationChannel(channel);
}
}
strings.xml:
<string name="notification_chnnl_location">Location polling</string>
<string name="notification_chnnl_location_descr">You will see notifications on this channel ONLY during location polling</string>
And I call the method every time before I'm going to show a notification of the type:
...
NotificationUtil.registerLocationNotifChnnl(this);
return new NotificationCompat.Builder(this, NotificationUtil.NOTIFICATION_CHANNEL_ID_LOCATION)
.addAction(R.mipmap.ic_launcher, getString(R.string.open_app),
activityPendingIntent)
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.remove_location_updates),
servicePendingIntent)
.setContentText(text)
...
Another typical problem - channel default sound - described here: https://stackoverflow.com/a/45920861/2133585