Android 12媒体通知大图标无法更新问题求助
问题解决:Android 12 MediaStyle通知大图标无法更新
问题根源
Android 12(API 31)起,使用MediaStyle并关联MediaSession的媒体通知,系统会优先从MediaSession的Metadata中读取大图标,而非直接使用通知setLargeIcon()设置的内容。同时,Android 12对MediaSession的Bitmap缓存策略做了严格限制:如果更新Metadata时传入的是同一个Bitmap实例,系统会判定为无变化,不会触发UI更新——这就是你看到标题/歌手能更新,但大图标不动的原因。而Android 8.1没有这个缓存校验逻辑,所以之前的代码能正常工作。
修复方案
- 完全依赖MediaSession Metadata提供大图标:既然MediaStyle下系统优先读这里,就不要再依赖
setLargeIcon(),把所有图标更新逻辑集中到Metadata里。 - 每次更新使用全新的Bitmap实例:通过
Bitmap.copy()创建副本,或者确保每次更新的Bitmap都是新生成的,绕过系统的缓存校验。
修改后的代码示例
// 关键:创建Bitmap副本,避免复用旧实例 Bitmap updatedImage = image.copy(image.getConfig(), true); // 更新MediaSession Metadata,使用新的Bitmap实例 mediaSession.setMetadata(new MediaMetadataCompat.Builder() .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, updatedImage) .putBitmap(MediaMetadata.METADATA_KEY_ART, updatedImage) // 这个是系统优先读取的key .putLong(MediaMetadata.METADATA_KEY_DURATION, -1L) .putString(MediaMetadata.METADATA_KEY_TITLE, BASLIK) .putString(MediaMetadata.METADATA_KEY_ARTIST, ISIM) .build()); stateBuilder = new PlaybackStateCompat.Builder(); stateBuilder.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS | PlaybackStateCompat.ACTION_SKIP_TO_NEXT); stateBuilder.setState(PlaybackStateCompat.STATE_PLAYING, 0, 1.0f); mediaSession.setPlaybackState(stateBuilder.build()); // 通知构建时可以移除setLargeIcon(),因为系统会从MediaSession取 notification = new NotificationCompat.Builder(context, CHANNEL_ID) .setContentTitle(BASLIK) .setContentText(ISIM) .setSmallIcon(R.drawable.ic_launcher_foreground) .addAction(R.drawable.ic_previous, "Previous", prevPendingIntent) .addAction(icon, "Play", playPendingIntent) .addAction(R.drawable.ic_next, "Next", nextPendingIntent) .setOnlyAlertOnce(true) .setPriority(Notification.PRIORITY_LOW) .setOngoing(true) .setShowWhen(false) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setStyle(new androidx.media.app.NotificationCompat.MediaStyle() .setShowActionsInCompactView(0, 1, 2) .setMediaSession(mediaSession.getSessionToken())); notificationManager.notify(Integer.parseInt(CHANNEL_ID), notification.build());
额外注意点
- 如果你是从网络加载图片,确保每次加载的Bitmap都是新实例,不要复用缓存的Bitmap对象。
- 若还是不生效,可以尝试在更新Metadata后,先调用
mediaSession.setActive(false),再调用mediaSession.setActive(true),强制系统刷新会话状态。
内容的提问来源于stack exchange,提问作者AllahinAskeri
相关产品推荐
相关产品推荐

