Updating to Android Oreo Continued
After a bug report and a bit of free time, I decided to get Media Button Overlay finally published and up to par with the latest API upgrades. Some things from the Developer Preview changed, so I decided to document the couple of changes needed to get things fully operational again.
Bumping the API Version
The obvious easy change - changing the compileSdkVersion
, buildToolsVersion
, and targetSdkVersion
in my Gradle build file:
android {
compileSdkVersion 27
buildToolsVersion "27.0.1"
// ...
defaultConfig {
// ...
minSdkVersion 14
targetSdkVersion 27
// ...
}
}
I also had to update the Gradle version and support library versions, but Android Studio handled this for me already.
Starting the Service
The startServiceInForeground
method of the NotificationManager was removed. Luckily, something a bit more straightforward was added to Context instead: startForegroundService
. It's like startService
, but requiring that foreground service promotion happens within an ANR interval.
..
On that note, I moved foreground promotion to the service onStartCommand
:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(NOTIFICATION_ID, MainActivity.getForegroundNotification(this));
return START_NOT_STICKY;
}
Notification Channel
Android Oreo also requires that notifications be added to a channel. I either overlooked this entirely in the first developer preview or it wasn't made apparent/wasn't a thing at the time. A notification channel helps the system categorize notifications properly in the shade, and are created by the developer at execution.
// ...
if(Build.VERSION.SDK_INT >= 26) {
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(getPackageName(), "Media Button Overlay", NotificationManager.IMPORTANCE_LOW);
channel.setDescription("Persisting notifications for Media Button Overlay");
channel.enableLights(false);
channel.enableVibration(false);
manager.createNotificationChannel(channel);
}
// ...
I do this at app start. Creating a notification channel, then attempting to recreate it just uses the existing one, so no excess channels are created.
I had to switch from the NotificationCompat builder to the standard Notification builder. This is so I can add the channel ID properly to the notification when it is launched. This is done with the setChannelId
method. I also modified it to work properly for lower supported Android versions, as I don't want to modify the minimum requirements. Here is the snippet:
// ...
Notification.Builder builder = new Notification.Builder(context)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(context.getResources().getString(R.string.app_name))
.setContentText(context.getResources().getString(text_resource))
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setOngoing(true);
if(Build.VERSION.SDK_INT < 26) {
builder.setPriority(Notification.PRIORITY_LOW);
}
else {
builder.setChannelId(context.getPackageName());
}
if(Build.VERSION.SDK_INT < 16) {
return builder.getNotification();
}
return builder.build();
Final Thoughts
I should probably pay more attention to final release notes, or changes between developer previews, as it was a bit frustrating to have to change some more things around. Regardless, fixing it up was much less painful than the initial change was. A copy of my diff for Media Button Overlay can be found here (again, ignore IDE files).