Vladislav Varslavans
Vladislav Varslavans

Reputation: 2934

How to correctly save URI to file in preferences

In my app I want user to select a file that should be used to read\write data and then "remember" this file URI to be used when app restarts.

I get file URI from user using:

Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
...
startActivityForResult(intent, CREATE_FILE);

and all relevant stuff, which works fine.

Then I try to store the URI in preferences:

SharedPreferences sharedPreferences = context.getSharedPreferences(PREFERENCES_FILE_KEY, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(DATA_FILE_NAME_KEY, dataFileUri.getPath());
editor.apply();
Log.i(TAG, "Saved data file URI: " + dataFileUri.getPath());

Here I notice that the URI that is stored looks like: /document/31 which doesn't seem right to me.

On app restart I retrieve URI from preferences:

SharedPreferences sharedPreferences = context.getSharedPreferences(PREFERENCES_FILE_KEY, Context.MODE_PRIVATE);
String dataFileText = sharedPreferences.getString(DATA_FILE_NAME_KEY, null);
Log.i(TAG, "File uri from preferences: " + dataFileText);
return Optional.ofNullable(dataFileText)
                       .map(File::new)
                       .map(Uri::fromFile);

Obviously I get same URI: /document/31 which obviously does not work anymore to open a file:

java.io.FileNotFoundException: /document/31

This is how I try to read a file:

InputStream inputStream = context.getContentResolver().openInputStream(uri);

I've tried the solutions proposed:

  1. https://stackoverflow.com/a/39850724/4174003
  2. https://www.dev2qa.com/how-to-get-real-file-path-from-android-uri/
  3. Using ContentResolver.query.. in a similar way: https://stackoverflow.com/a/16511111/4174003

All these did not work and for me looks quite strange and ugly.

Question

What is the correct way in Android to persist URI for use through application start/stop cycles?

Upvotes: 2

Views: 602

Answers (1)

dev.bmax
dev.bmax

Reputation: 10591

Instead of saving the path part of the URI, please try to save the whole URI as text using dataFileUri.toString(). It should look something like "content://document/31".

And after reading it from the SharedPreferences use Uri.parse(uriString) to recover the URI.

Upvotes: 2

Related Questions