android - 使用 Android 10 (Q) 且 targetSdkVersion = 29 在 ExoPlayer 上播放歌曲的正确方法是什么?

标签 android exoplayer exoplayer2.x android-10.0

根据 Android 10 (Q) 的最新变化,尝试在应用(面向 sdk 版本 29 并运行 Android 10)上播放用户设备上的歌曲)使用ExoPlayer,在控制台上打印以下日志并失败(歌曲未播放):

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) 

我在互联网上找到的解决该问题的一种方法是在 list 的 <application> 上添加以下属性标签:

android:requestLegacyExternalStorage="true"

该解决方案的问题在于它似乎是暂时的,可能很快就会被弃用。


在这些规范下处理这些变化的正确方法是什么?

最佳答案

经过进一步的试验,我能够使用媒体的 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)

它成功播放了歌曲,没有抛出任何异常。

关于android - 使用 Android 10 (Q) 且 targetSdkVersion = 29 在 ExoPlayer 上播放歌曲的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59036747/

相关文章:

Android Xoom 加速度计精度总是不可靠

android - 无法运行 AVD(模拟器)

android - AmbiguousViewMatcherException Espresso

android - 是否有使用字幕的 ExoPlayer + Leanback 库示例?

android - SimpleExoPlayerView 是否有 Controller 可见性更改事件?

android - 如何在 Exoplayer Android 库中为 HLS 流设置 CloudFront Cookies?

android - 使用 HTML5 API 创建后台 Android 进程

java - 更改事件监听器中的变量?

android - exoplayer android 中的时间栏问题

java - 有时在 exoplayer 中的视频缓冲速度很慢?