You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13前台服务通知METADATA_KEY_ALBUM_ART重叠问题求助

问题:Android 13前台服务通知位图重叠

升级Pixel设备到Android 13后,更新前台服务通知时出现专辑封面位图重叠——旧封面不会被清除,与新封面叠加显示。

相关代码

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)
}

执行流程

  • 调用refreshNotification方法,尝试下载可用图片
  • 从refreshNotification中调用buildNotification方法
  • 根据前台服务是否已启动,选择启动服务或更新通知

已尝试设置setLargeIcon(bitmap),问题依旧。


解决办法

1. 强制清空MediaSession元数据

Android 13的MediaSession元数据缓存机制可能导致旧Bitmap未被清除,更新元数据前先调用clear()清空所有原有元数据:

if (imageBitmap != null) {
    mediaSession.setMetadata(
        MediaMetadataCompat.Builder()
            .clear() // 清空原有元数据
            .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()
            .clear() // 清空原有元数据
            .putString(MediaMetadata.METADATA_KEY_TITLE, name)
            .putString(MediaMetadata.METADATA_KEY_ARTIST, "Artist")
            .build()
    )
}

2. 确保每次更新都创建全新的MediaStyle实例

避免复用MediaStyle对象,每次构建通知时都创建新的MediaStyle实例(你的代码已实现,但需确认无外部复用情况):

setStyle(
    androidx.media.app.NotificationCompat.MediaStyle()
        .setShowActionsInCompactView(0)
        .setMediaSession(mediaSession.sessionToken)
        .setShowCancelButton(true)
        .setCancelButtonIntent(stopIntent)
)

3. 处理Bitmap实例,避免缓存复用

对下载的Bitmap进行拷贝,生成全新实例后再传入通知:

val req = ImageRequest.Builder(this@SoundPlayerService)
    .data(icon)
    .target { result ->
        val originalBitmap = (result as BitmapDrawable).bitmap
        // 拷贝生成新Bitmap实例
        val newBitmap = originalBitmap.copy(originalBitmap.config, true)
        buildNotification(newBitmap, item)
    }
    .build()

同时在buildNotification中同步设置setLargeIcon(newBitmap)和MediaMetadata中的专辑封面。

4. 临时方案:重启前台服务

如果上述方法无效,可尝试先停止前台服务再重新启动,强制清除旧通知:

private fun updateNotification(builder: NotificationCompat.Builder){
    Timber.i("UPDATE FOREGROUND SERVICE")
    // 停止前台但不清除通知
    stopForeground(false)
    // 重新启动前台服务
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        startForeground(ONGOING_NOTIFICATION_ID, builder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
    } else {
        startForeground(ONGOING_NOTIFICATION_ID, builder.build())
    }
}

此方法可能导致通知短暂闪烁,但能有效解决重叠问题。


内容的提问来源于stack exchange,提问作者brettywhite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 21:01:06