Android MediaPlayer 无法设置DataSource uri

问题描述 投票:0回答:2

我正在尝试使用sharedPreferences 存储以前播放过的歌曲的uri。但是,当如果获取并重建 uri 以播放歌曲时,我会收到以下错误消息:

05-03 20:43:14.642 8617-8716/com.stopwatch.app W/MediaPlayer:无法在客户端打开文件;尝试服务器端:java.lang.SecurityException:权限拒绝:从ProcessRecord{2c95b0 8617:com.stopwatch.app/u0a175}(pid = 8617,uid = 10175)打开提供程序com.android.providers.media.MediaDocumentsProvider需要android。权限.MANAGE_DOCUMENTS 或 android.permission.MANAGE_DOCUMENTS

05-03 20:43:14.658 8617-8716/com.stopwatch.app I/MediaPlayer: setDataSource(content://com.android.providers.media.documents/document/audio%3A18504)

05-03 20:43:14.661 8617-8716/com.stopwatch.app E/MediaPlayer:无法创建媒体播放器

05-03 20:43:14.662 8617-8716/com.stopwatch.app W/System.err: java.io.IOException: setDataSource 失败。: status=0x80000000

我不明白我需要 android.permission.MANAGE_DOCUMENTS 并且我的 IDE 告诉我这是一个仅适合系统应用程序的权限。我的代码如下所示:

if(prefs.contains("AudioFile")){
        try {
            String UriString = prefs.getString("AudioFile", null);
            Uri uri = Uri.parse(UriString);
            mediaPlayer.setDataSource(this, uri);
            Gdx.app.log("Android Media Player", "Successfully got data");
        } catch (IOException e) {
            e.printStackTrace();
            Gdx.app.log("Android Media Player", e.getMessage());
        }
        try {
            mediaPlayer.prepare();
            Gdx.app.log("Android Media Player", "Successfully prepared content");
        } catch (IOException e) {
            e.printStackTrace();
            Gdx.app.log("Android Media Player", e.getMessage());
        }
    }

我尝试在

onCreate
方法中运行它(这似乎是一个坏主意),并通过单击按钮调用的另一种方法运行它,但都失败了。

请注意,如果我启动应用程序并通过启动媒体播放器的意图检索 uri:

protected void onActivityResult (int requestCode, int resultCode, Intent data){
    if(requestCode == MUSIC_REQUEST){
        if(resultCode == RESULT_OK){
            Uri myUri = data.getData();
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString("AudioFile", myUri.toString());
            editor.commit();
            System.out.println(myUri);
            try {
                mediaPlayer.setDataSource(this, myUri);
                Gdx.app.log("Android Media Player", "Succesfully got data");
            } catch (IOException e) {
                e.printStackTrace();
                Gdx.app.log("Android Media Player", e.getMessage());
            }
            try {
                mediaPlayer.prepare();
                Gdx.app.log("Android Media Player", "Succesfully prepared content");
            } catch (IOException e) {
                e.printStackTrace();
                Gdx.app.log("Android Media Player", e.getMessage());
            }
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

我没有问题,即使我用 mediaPlayer.setDataSource(this, Uri.parse(myUri.toString)) 替换也没有问题。

java android android-mediaplayer
2个回答
4
投票

您不能坚持一个

Uri
值并期望它稍后起作用。那些拥有
content
方案 可以让您在很短的时间内访问内容

如果您使用

ACTION_OPEN_DOCUMENT
获取
Uri
,您可以通过 takePersistableUriPermission()
 上的 
ContentResolver
请求长期访问内容
。不过,您仍然需要处理用户可能移动或删除内容的可能性。

如果您使用

ACTION_GET_CONTENT
来获取
Uri
,请切换到
ACTION_OPEN_DOCUMENT
(如果您的
minSdkVersion
为 19 或更高)或复制内容,然后使用您的副本。


0
投票

我遇到了同样的问题,我将 URI 存储在共享首选项中以供将来使用,第一次当我播放音频时它工作正常,但当我清除背景时它显示错误。 我给出了我用来解决问题的代码。

public void playSound(Context context, Uri uri) {
    stopSound();  // Stop any currently playing sound

    /*- don't remove this code it's important for android 11 or above -*/
    ContentResolver resolver = context.getContentResolver();
    int takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION;
    resolver.takePersistableUriPermission(uri, takeFlags);
    /*----------------------------------------------------------------*/
    try {
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setDataSource(context, uri);
        mediaPlayer.setLooping(true);
        mediaPlayer.prepare();
        mediaPlayer.start();

    } catch (Exception e) {
        Log.d(TAG, "playSound: " + e.getMessage());
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.