I've noticed since my pixel updated to Android 13, updating foreground service bitmaps overlap.
Example:
As you can see, instead of clearing, it layers on top. My notification code is as follows:
private fun refreshNotification() {
val sounds = // code
if (sounds.isEmpty()) {
if (!audioFocusTakenBackground) {
stopForegroundService()
}
return
} else {
val item = // code
val icon = // code
if (icon != null && icon.isNotEmpty()) {
val loader = this@SoundPlayerService.imageLoader
val req = ImageRequest.Builder(this@SoundPlayerService)
.data(icon)
.target { result ->
val bitmap = (result as BitmapDrawable).bitmap
buildNotification(bitmap, item)
}
.build()
loader.enqueue(req)
} else {
buildNotification(null, item)
}
}
}
private fun buildNotification(imageBitmap: Bitmap?, item: MediaItem){
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
val name: String = // code
// update session metadata
mediaSession.isActive = true
if (imageBitmap != null) {
mediaSession.setMetadata(
MediaMetadataCompat.Builder()
.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, imageBitmap)
.putString(MediaMetadata.METADATA_KEY_TITLE, name)
.putString(MediaMetadata.METADATA_KEY_ARTIST, "Artist")
.build()
)
} else {
mediaSession.setMetadata(
MediaMetadataCompat.Builder()
.putString(MediaMetadata.METADATA_KEY_TITLE, name)
.putString(MediaMetadata.METADATA_KEY_ARTIST, "Artist")
.build()
)
}
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
setContentTitle(getString(R.string.action_now_playing))
setContentText(name)
setSmallIcon(R.drawable.ic_icon_small)
setContentIntent(relaunchPendingIntent())
setSilent(true)
setCategory(NotificationCompat.CATEGORY_SERVICE)
setAutoCancel(false)
color = this@SoundPlayerService.getColor(R.color.magenta)
addAction(NotificationCompat.Action(R.drawable.ic_playbar_stop, getString(R.string.action_stop), stopIntent))
setStyle(
androidx.media.app.NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0)
.setMediaSession(mediaSession.sessionToken)
.setShowCancelButton(true)
.setCancelButtonIntent(stopIntent)
)
}
if (isForegroundActive){
updateNotification(builder)
} else {
startForegroundApp(builder)
}
}
private fun updateNotification(builder: NotificationCompat.Builder){
Timber.i("UPDATE FOREGROUND SERVICE")
val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(ONGOING_NOTIFICATION_ID, builder.build());
}
private fun startForegroundApp(builder: NotificationCompat.Builder){
if (!audioFocusTakenBackground && Application.instance.isAppInForeground && !isForegroundActive) {
isForegroundActive = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(
ONGOING_NOTIFICATION_ID,
builder.build(),
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
)
true
} else {
startForeground(
ONGOING_NOTIFICATION_ID,
builder.build()
)
true
}
}
}
private fun stopForegroundService(){
isForegroundActive = false
stopForeground(true)
}
#1 refreshNotification is called, it tries to download an image if available
#2 buildNotification is called from refreshNotification
#3 Depending on whether the foreground service has been started already or not, it is either started, or the notification updated.
Just curious if anyone else has encountered this and if there is a workaround.
Thanks!
EDIT:
also tried setting setLargeIcon(bitmap) as well, to no avail

