[随着Android 10(Q)的最新更改,尝试使用ExoPlayer在用户的设备上播放用户设备上的歌曲(针对sdk版本29并运行Android 10),将打印以下内容登录控制台并失败(未播放歌曲):
E/libprocessgroup: Error encountered killing process cgroup uid 99420 pid 20294: Permission denied
com.google.android.exoplayer2.upstream.FileDataSource$FileDataSourceException: java.io.FileNotFoundException: /storage/emulated/0/Music/Nirvana/[1989] - Bleach/01 - Blew.mp3: open failed: EACCES (Permission denied)
at com.google.android.exoplayer2.upstream.FileDataSource.open(FileDataSource.java:73)
at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:257)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:939)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:394)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.io.FileNotFoundException: /storage/emulated/0/Music/Nirvana/[1989] - Bleach/01 - Blew.mp3: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:496)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:289)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:152)
at com.google.android.exoplayer2.upstream.FileDataSource.open(FileDataSource.java:65)
at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:257)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:939)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:394)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7255)
at libcore.io.IoBridge.open(IoBridge.java:482)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:289)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:152)
at com.google.android.exoplayer2.upstream.FileDataSource.open(FileDataSource.java:65)
at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:257)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:939)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:394)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
我在Internet上找到的解决该问题的一种方法是在清单的<application>
标签上添加以下属性:
android:requestLegacyExternalStorage="true"
该解决方案的问题在于它似乎是临时的,可能很快就会被弃用。
在那些规范下处理这些更改的正确方法是什么?
请参见https://stackoverflow.com/a/59037794/2373819
但是查看Exoplayer源代码。
说
file = new RandomAccessFile(dataSpec.uri.getPath(), "r");
并且在API 29及更高版本中,公共文件中不能访问文件路径。
您应该在ExoPlayer中引发一个错误,以改用Java从fileDescriptor
到contentresolver
的Java
经过进一步的试验,我能够使用媒体的Uri
使用ExoPlayer播放歌曲。
// id col = `MediaStore.Audio.Media._ID`
val id = cursor.getLong(idColIndex)
val uri = ContentUris.withAppendedId(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
id
)
...
val songSource = ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(uri)
它成功播放了这首歌,没有引发任何异常。