将 uri 保存到 sharedPreferences 并使用 mediaplayer 播放

Jul*_*s B 7 android uri sharedpreferences android-mediaplayer

这是我用来将 Uri 的字符串表示形式保存到 SharedPreferences 的代码:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQ_CODE_PICK_SOUNDFILE && resultCode == Activity.RESULT_OK){
        if ((data != null) && (data.getData() != null)){
            SharedPreferences sharedPref = getSharedPreferences("customName", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPref.edit();
            editor.putString("uritostring", data.getData().toString());
            editor.apply();

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,当我在此处附加以下两个中的任何一个时,它都可以正常工作:

MediaPlayer mp=MediaPlayer.create(this,data.getData());

MediaPlayer mp=MediaPlayer.create(this,Uri.parse(data.getData().toString()));
Run Code Online (Sandbox Code Playgroud)

但是,当我稍后在这样的另一个活动中尝试创建 MediaPlayer 时,它不起作用:

SharedPreferences sharedPref = getSharedPreferences("customName", Context.MODE_PRIVATE);
Uri uri = Uri.parse(sharedPref.getString("uritostring","defaultUriString"));
mp.create(this,uri);
Run Code Online (Sandbox Code Playgroud)

我不知道保存和加载到 sharedPreferences 可以合理地产生什么区别。据我所知,从调试来看uri与上面的Uri.parse(data.getData().toString())的结果相同。

非常感谢任何帮助和指示。

此致

尤利乌斯

编辑:

我以为我通过MediaPlayer.create()使用getApplicationContext()上下文调用方法解决了这个问题,但是关闭应用程序并重新打开它会使方法调用再次失效。

Rec*_*cek 5

遇到了同样的问题,并在这里找到了解决方案: http:
//www.andreamaglie.com/access-storage-framework-uri-permission/
和这里
/sf/answers/1763612231/

当您使用 KitKat+ (SDK 19+) 时,此修复将为您提供帮助。基本上,当您从首选项中保存和检索 URI 时,您将失去访问该文件的权限。通过所描述的步骤,您可以由系统保留此权限,以便应用程序稍后将被允许访问该文件。例如,我用它来选择警报声音,稍后将由触发的服务检索并播放。

总结一下(也以防万一在一段时间后无法访问第一个站点):

需要许可

<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
Run Code Online (Sandbox Code Playgroud)

获取 URI(使用 ACTION_OPEN_DOCUMENT 很重要)

Intent audioIntent = new Intent();
audioIntent.setType("audio/*");
audioIntent.setAction(Intent.ACTION_OPEN_DOCUMENT);
audioIntent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(audioIntent, PICK_AUDIO_REQUEST);
Run Code Online (Sandbox Code Playgroud)

读取URI并保留读取权限(在onActivityResult中)

        Uri alarmSoundUri = data.getData();

        getActivity().grantUriPermission(getActivity().getPackageName(), alarmSoundUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
        final int takeFlags = data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION;
        // Check for the freshest data.
        //noinspection WrongConstant
        getActivity().getContentResolver().takePersistableUriPermission(alarmSoundUri, takeFlags);
        getPrefs().setAlarmSoundUri(alarmSoundUri.toString());
Run Code Online (Sandbox Code Playgroud)

从首选项中检索 URI

String alarmSoundUri = getPrefs().getAlarmSoundUri();
Uri parsedUri = Uri.parse(alarmSoundUri);
...
Run Code Online (Sandbox Code Playgroud)

getPrefs()...显然必须是您自己的偏好实现。