Xamarin.Android中如何获取通知消息内的大图标(专辑封面)?
问题
我创建了一个服务监听通知栏以抓取音乐媒体信息,目前能获取音乐标题和歌手信息,但无法获取专辑封面。尝试使用已过时的largeIcon返回null,调用GetLargeIcon()也无法获取,请问该如何解决?
我的代码如下:
public override void OnNotificationPosted(StatusBarNotification sbn) { string packageName = sbn.PackageName; if (!packageName.Contains("clash")) { if (packageName.Contains("music")) { var info = sbn.Notification.Extras; //var largeIcon = sbn.Notification.LargeIcon; var title = info.Get("android.title")?.ToString(); var singer = info.Get("android.text")?.ToString(); //var subText = info.Get("android.subText")?.ToString(); Intent intent = new Intent(AppWidgetConstants.UpdateMusicInfo); intent.PutExtra("music_title", title); intent.PutExtra("music_singer", singer); //intent.PutExtra("music_album", largeIcon); XApp.Application.Context.SendBroadcast(intent); } } base.OnNotificationPosted(sbn); }
解决方案
1. 从通知Extras中读取大图标
大部分音乐APP会把专辑封面放在通知的EXTRA_LARGE_ICON或EXTRA_LARGE_ICON_BIG字段中,你可以直接从Notification.Extras中获取:
// 尝试获取标准大图标 Bitmap albumCover = info.GetParcelable(Notification.ExtraLargeIcon) as Bitmap; // 如果为空,尝试获取更大尺寸的图标 if (albumCover == null) { albumCover = info.GetParcelable(Notification.ExtraLargeIconBig) as Bitmap; }
2. 通过MediaSessionToken获取媒体元数据
正规音乐APP通常会绑定MediaSession发布媒体通知,你可以通过通知的MediaSessionToken获取完整的媒体元数据(包括专辑封面):
var mediaSessionToken = sbn.Notification.MediaSessionToken; if (mediaSessionToken != null) { var sessionToken = mediaSessionToken.GetSessionToken(); var connector = new MediaSessionConnector(sessionToken); connector.Connect(new MediaSessionConnector.Callback { OnMetadataChanged = (session, metadata) => { // 获取专辑封面 Bitmap albumCover = metadata.GetBitmap(MediaMetadata.MetadataKeyAlbumArt); // 发送包含封面的广播 SendMusicBroadcast(title, singer, albumCover); } }); }
3. 解决Bitmap的Intent传递问题
直接通过Intent传递Bitmap可能因尺寸过大导致异常,建议转为字节数组传递:
发送端
private void SendMusicBroadcast(string title, string singer, Bitmap albumCover) { Intent intent = new Intent(AppWidgetConstants.UpdateMusicInfo); intent.PutExtra("music_title", title); intent.PutExtra("music_singer", singer); if (albumCover != null) { using (MemoryStream stream = new MemoryStream()) { albumCover.Compress(Bitmap.CompressFormat.Png, 100, stream); intent.PutExtra("music_album_bytes", stream.ToArray()); } } XApp.Application.Context.SendBroadcast(intent); }
接收端
byte[] coverBytes = intent.GetByteArrayExtra("music_album_bytes"); if (coverBytes != null) { Bitmap albumCover = BitmapFactory.DecodeByteArray(coverBytes, 0, coverBytes.Length); // 处理封面逻辑 }
4. 权限与兼容性说明
- 确保你的APP已申请
android.permission.ACCESS_NOTIFICATION_POLICY权限,并且用户在系统设置中开启了通知访问权限。 - 部分自定义ROM或小众音乐APP可能限制通知内容读取,这种情况需要针对特定APP做适配。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

