RK3588解决无法音乐/相册等无法同步问题
RK3588解决无法音乐/相册等无法同步问题
背景
最近在做一个项目的时候发现音乐APP无法自动识别设备中的音频,这个APP是芯片厂商写的,可能由于年代久远,有这种奇怪的bug。复现步骤如下:1、使用adb push音频文件到/sdcard/Music/
文件夹下或使用文件管理器从外部设备(如U盘)将音频文件复制到/sdcard/Music/
文件夹中。2、打开音乐APP,发现找不到任何音频文件。
神奇的是,它可以识别到U盘内的音频文件,如果复制到/sdcard/Music/
文件夹后重启,重启后又可以查找到/sdcard/Music/
中的音频文件了。我一开始以为是APP初始化时会去扫描,因此将该APP进程kill掉,再启动发现依旧查找不到任何音频文件,这就说明是重启时有我不知道的地方帮我做了同步的功能。因此写了一个简易的demo来进行测试。
排查过程
先看一下是如何查询系统中的音乐文件的。下面是我写的一个方法,与源码方法基本一样,其中Music
是一个data class
查询音乐代码
fun initMusicList(context: Context): List<Music> {
val musicList = ArrayList<Music>()
val cols = arrayOf(
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.DURATION
)
val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
val cursor = context.contentResolver.query(
uri,
cols,
null,
null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER
)
if (cursor != null && cursor.moveToFirst()) {
do {
val music = Music(
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)),
cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)),
cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))
)
musicList.add(music)
} while (cursor.moveToNext())
cursor.close()
}
return musicList
}
我用了一个简易的RecyclerView
用于展示读取到的信息,/sdcard/Music/
中的文件内容与RecyclerView
所得到的内容如下
现在一切正常,是吧。那让我们添加一个音乐到/sdcard/Music/
文件夹下看看会怎么样:
可以看到我已经把我们的app给kill掉了
神奇的事情来了:重新打开APP后,它依旧只有三首歌,这说明我们新添加的3.wma这首歌没有被识别到MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
路径中。
这时候我们只需要执行以下命令就可以了:
adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/Music/
不难理解,这就是一个让设备在我们所指定的文件夹/sdcard/Music/
下查找媒体文件的命令,这里的/sdcard/Music/
可以根据实际需要进行改变。这样我们就能把刚添加的音频文件“刷新” 到媒体库了。那么如何在代码中使用呢?可以参考下面的方法:
Java
版本
private void syncMusic(Context context) {
String path = Environment.getExternalStorageDirectory().getPath() +
File.separator + "Music";
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.fromFile(new File(path))));
}
Kotlin
版本
private fun syncMusic(context: Context) {
val path = Environment.getExternalStorageDirectory().path + File.separator + "Music"
context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(File(path))))
}
在你的Activity、Fragment等有context的地方调用,但是需要注意的是,这是一个耗时方法,因此我们最好是开一个工作线程去执行它。