Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save uri to sharedPreferences and play with mediaplayer

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.

like image 301
Julius B Avatar asked Jun 29 '15 12:06

Julius B


1 Answers

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.

like image 109
Recek Avatar answered Nov 16 '22 15:11

Recek