Android车载媒体应用:MediaDescription.Builder无法设置MediaItem图标
我正在开发一款使用MediaBrowserService的Android车载媒体应用,尝试将drawable文件夹中的图片设置为MediaItem的MediaDescription图标,但图标未能成功显示。
我的代码如下:
@Override public void onLoadChildren(final String parentMediaId, final Result<List<MediaBrowser.MediaItem>> result) { // Return the children of the given parent media item List<MediaBrowser.MediaItem> children = getChildren(parentMediaId); result.sendResult(children); } private List<MediaBrowser.MediaItem> getChildren(String parentId) { int drawableResourceId = R.drawable.finallogo; Uri drawableUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + "com.examole.app" + "/" + drawableResourceId); List<MediaBrowser.MediaItem> children = new ArrayList<>(); if (parentId.equals("root")) { children.add(new MediaBrowser.MediaItem(new MediaDescription.Builder() .setMediaId("media_item_1") .setTitle("Browsable Item") .setSubtitle("test") .setIconUri(drawableUri) .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE)); } else { children.add(new MediaBrowser.MediaItem(new MediaDescription.Builder() .setMediaId("media_item_1") .setTitle("Playable Item") .setSubtitle("test2") .setIconUri(drawableUri) .build(), MediaBrowser.MediaItem.FLAG_PLAYABLE)); } return children; }
根据官方文档:
Artwork for media items must be passed as a local URI using either ContentResolver.SCHEME_CONTENT or ContentResolver.SCHEME_ANDROID_RESOURCE. This local URI must resolve to either a bitmap or a vector drawable in the application’s resources. For MediaDescriptionCompat
我已尝试构建SCHEME_ANDROID_RESOURCE类型的Uri,但图标仍未显示。请问是否需要提前缓存图片?或者提供正确的设置本地drawable为媒体项图标的方法?
1. 首要修复:包名拼写错误
你的代码中硬编码了包名com.examole.app,这里是example的拼写错误(写成了examole),这会直接导致Uri无法解析资源。永远不要硬编码包名,改用getPackageName()动态获取:
String packageName = getPackageName(); Uri drawableUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + packageName + "/" + drawableResourceId);
2. 正确构建Android资源Uri
构建android.resource Uri有两种可靠方式:
- 方式一:通过资源名(推荐,易维护)
Uri drawableUri = Uri.parse("android.resource://" + getPackageName() + "/drawable/finallogo");
- 方式二:通过资源ID
Uri drawableUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.drawable.finallogo);
两种方式均可正常工作,推荐使用资源名,避免因资源ID变动导致的问题。
3. 兼容性优化:使用MediaDescriptionCompat
车载系统版本差异较大,建议使用MediaDescriptionCompat和MediaBrowserCompat.MediaItem构建媒体项,兼容性更稳定:
private List<MediaBrowserCompat.MediaItem> getChildren(String parentId) { List<MediaBrowserCompat.MediaItem> children = new ArrayList<>(); String packageName = getPackageName(); Uri drawableUri = Uri.parse("android.resource://" + packageName + "/drawable/finallogo"); if (parentId.equals("root")) { MediaDescriptionCompat description = new MediaDescriptionCompat.Builder() .setMediaId("media_item_1") .setTitle("Browsable Item") .setSubtitle("test") .setIconUri(drawableUri) .build(); children.add(new MediaBrowserCompat.MediaItem(description, MediaBrowserCompat.MediaItem.FLAG_BROWSABLE)); } else { MediaDescriptionCompat description = new MediaDescriptionCompat.Builder() .setMediaId("media_item_1") .setTitle("Playable Item") .setSubtitle("test2") .setIconUri(drawableUri) .build(); children.add(new MediaBrowserCompat.MediaItem(description, MediaBrowserCompat.MediaItem.FLAG_PLAYABLE)); } return children; }
4. 关于缓存的说明
不需要提前缓存图片。MediaBrowser框架会自动根据Uri加载资源,只要Uri正确,系统会负责解析和显示,无需手动处理缓存逻辑。
5. 额外排查点
- 确认
R.drawable.finallogo确实存在于drawable目录(包括适配不同密度的drawable-xxxhdpi等),且文件名无大小写错误。 - 如果使用VectorDrawable,确保目标系统版本支持(Android 5.0+原生支持,低于该版本需添加vector兼容库)。
内容的提问来源于stack exchange,提问作者MadMan

