使用Android MediaStore为音频添加元数据标签不生效如何解决?
问题原因
- 你调用
contentResolver.insert()时传入的音频元数据(标题、艺术家、专辑),会在你写入音频文件内容后,被系统媒体扫描器读取文件内置的ID3标签覆盖,你下载的示例MP3自带的标签(或无标签)会直接替换你预先设置的值 - 未使用Android 10及以上要求的
IS_PENDING标记标记写入中的文件,系统可能提前触发媒体扫描,导致你设置的元数据失效
解决方法
修改createFile方法,遵循「标记为待写入→写入文件内容→更新元数据→取消待写入标记」的流程即可:
private long createFile(Context context, String fileName, InputStream fileContent) throws IOException { Uri audioCollection = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.Audio.Media.DISPLAY_NAME, fileName); contentValues.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mpeg"); // Android 10及以上添加待写入标记,避免系统提前扫描 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { contentValues.put(MediaStore.Audio.Media.IS_PENDING, 1); } ContentResolver contentResolver = context.getContentResolver(); Uri uri = contentResolver.insert(audioCollection, contentValues); if (uri == null) throw new IOException("无法创建MediaStore条目"); // 写入文件内容 try (FileOutputStream out = (FileOutputStream) contentResolver.openOutputStream(uri); FileChannel outChannel = out.getChannel(); ReadableByteChannel inChannel = Channels.newChannel(fileContent)) { outChannel.transferFrom(inChannel, 0, Long.MAX_VALUE); } // 写入完成后更新元数据,取消待写入标记 ContentValues updateValues = new ContentValues(); updateValues.put(MediaStore.Audio.Media.TITLE, "some title"); updateValues.put(MediaStore.Audio.Media.ARTIST, "some artist"); updateValues.put(MediaStore.Audio.Media.ALBUM, "some album"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { updateValues.put(MediaStore.Audio.Media.IS_PENDING, 0); } contentResolver.update(uri, updateValues, null, null); long id = Long.parseLong(uri.getLastPathSegment()); return id; }
注意事项
如果需要永久让标签生效,建议同时修改MP3文件本身的ID3标签,避免后续系统重新扫描媒体库时再次被文件内置标签覆盖,可使用第三方ID3编辑库实现本地文件标签修改。
内容的提问来源于stack exchange,提问作者nhcodes
相关产品推荐
相关产品推荐

