Search code examples
androidandroid-contentresolvermediastore

Saving media file path or URI to SQLite and getting it, best practice


My goal is to:

  • Save media file to External Storage (in my case it's photo).
  • Get file path or URI of saved data.
  • Save it to SQLite (either file path or content URI or smth else).
  • Be able to get correct URI to this content at any point in the future.

It's very similar to what other very popular application do - they create their directory in 'Pictures' folder and store there photos and use them in their applications while they're also available for viewing using gallery/file explorer etc.

As I understand recommended way to save media content (image, f.e.) is to use MediaStore API and as a result I get content URI, which I can use later. But then I read that these content URIs might be changed after re-scan of Media happens, so it looks it's not reliable. (For example if SD card is used and it's taken out and inserted again)

At the same time usage of absolute file paths is not recommended and there's tendency to deprecate APIs which use absolute file paths to work with External Storage. So it doesn't look reliable either.

I can only imagine the following solution:

  • Use unique auto-generated file name while saving (like UUID).
  • When I need to get content URI (f.e. want to render photo in ImageView) - I can use ContentResolver and search for content URI using file name filter.

Problem with this approach is that I have a lot of photos (gallery) and querying it using ContentResolver can affect performance significantly.

I feel like I'm over complicating things and missing something.


Solution

  • You are indeed overcomplicating things. Store file to the needed folder in the filesystem(it is better to name the folder under your app name)

    Store this path or URI path - whatever you like. (Do not hardcode passes though in your app - device vendors may have different base paths in their devices)

    As long as the folder is named the same and files in it named the same(as in your db) - you will be able to access them even if the sdcard was taken out and then put back in.

    There are possible complications after reindexing - but for the eight years I work as Android dev I encountered it only once, thus you can easily ignore this stuff.

    If you want to have more control over what you store and want to limit access to it - store data into the inner storage of your app - this way you will be 100% sure of where the data is and that it is not tampered with.

    Starting from Android 10 you have scoped storage - it is like internal storage but it may be even on an external sdcard.

    Here is a small overview of possible storage locations.

    And don't overthink it too much - it is a default usecase of the phone and it works just as you would expect - pretty ok and pretty stable.