This is the code I use to save the string representation of the Uri to the 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();
}
}
}
Note that when I append either of the following two right here it works without a problem:
MediaPlayer mp=MediaPlayer.create(this,data.getData());
MediaPlayer mp=MediaPlayer.create(this,Uri.parse(data.getData().toString()));
However when I try to create a MediaPlayer later in another activity like this, it does not work:
SharedPreferences sharedPref = getSharedPreferences("customName", Context.MODE_PRIVATE);
Uri uri = Uri.parse(sharedPref.getString("uritostring","defaultUriString"));
mp.create(this,uri);
I'm lost at what difference the saving and loading to sharedPreferences could reasonably make. From debugging as far as I can tell uri is identical to the result of Uri.parse(data.getData().toString()) from above.
Any help and pointers are greatly appreciated.
Best regards
Julius
EDIT:
I thought I solved this by calling the MediaPlayer.create()
method with the getApplicationContext()
context, but closing the application and reopening it renders the method call disfunctional again.
Had the same issue and found the solution here:
http://www.andreamaglie.com/access-storage-framework-uri-permission/
and here
https://stackoverflow.com/a/25194460/1993098
This fixes will help you, when you use KitKat+ (SDK 19+). Basically you loose the permission to access the file when you save and retrieve the URI from preferences. With the steps described you can persist this permission by the system and so the app will be allowed to access the file later. I for example used this to pick an alarm sound, which will than later be retrieved by an triggered service and played.
To sum it up (also in case the first site shouldn't be reachable after some time):
Permission needed
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
Getting the URI (it is important to use 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);
Reading the URI and persisting the permission to read (in 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());
Retrieving the URI from Preferences
String alarmSoundUri = getPrefs().getAlarmSoundUri();
Uri parsedUri = Uri.parse(alarmSoundUri);
...
getPrefs()... obviously must be your own preference implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With