How to manage all local storages in all versions (primary, secondary storage, sd card, usb)

767 Views Asked by At

Intro

Managing primary storage files + secondary storage files (local only): I will list all the informations I already have and would like you to extend them or correct me so that this question hopefully becomes a overview that summarises all the main informations someone has to know before starting to work with LOCAL storages. I'm sure many people are looking for such an overview...

Overview

Normally you have following storages:

  • a primary storage (always directly accessible, mostly on the internal storage, but it's up to the phone manufactorer)
  • a secondary storage (directly accessible for android <=4.3)
  • other external storages like USB OTG for example...

Following questions raise up:

  1. How to find out all available local storages + find out the type (primary, secondary resp. internal, sd card, usb)?

  2. List all available files on the storages

    2.1 Which storages will be indexed via the MediaStore?

    2.2 How to get all files via the MediaStore?

    2.3 How to get all files without MediaStore?

  3. How to edit files on those storages?

Most of the things I already know, mostly my questions are based on what data is indexed by the media store, how to find out which storages are available, how to identify a storage... So I post an answer that answers most of the parts and that also shows a status for each questions <=> android version pair so that it's easily visible what informations are still missing

Status - feel free to extend/correct my answers to the questions if you know more or I'm wrong

Android < 4.4

  • Question 1 - partially known ✖
  • Question 2.1 - unknown ✖
  • Question 2.2 - known ✔
  • Question 2.3 - known ✔
  • Question 3 - known ✔

Android 4.4

  • Question 1 - partially known ✖
  • Question 2.1 - unknown ✖
  • Question 2.2 - known ✔
  • Question 2.3 - partially known ✖
  • Question 3 - partially known ✖

Android >=5

  • Question 1 - partially known ✖
  • Question 2.1 - unknown ✖
  • Question 2.2 - known ✔
  • Question 2.3 - known ✔
  • Question 3 - known ✔
1

There are 1 best solutions below

0
On

----------------------------------------------

Android <4.4:

----------------------------------------------

1. How to find out all available local storages + find out the type (primary, secondary resp. internal, sd card, usb)? (partially known ✖)

I'm not sure how to distinguish between the available storage correctly... Getting the primary storage path is possible via File primaryStorage = context.getExternalCacheDir(). Or you can get all paths via File[] dirs = ContextCompat.getExternalFilesDirs(context, null);. This will list all available paths, not sure if it will return usb storages as well or if it reliable adds sd card paths...

I actually don't know how to reliably find out which path is internal, whcih one is an sd card and which one is an usb drive

2.1 Which storages will be indexed via the MediaStore? (unknown ✖)

I've seen that sometimes external storages are indexed and sometimes not, I'm not sure what's the default behaviour...

2.2 How to get all files via the MediaStore? (known ✔)

Just list all files via a query on the ContentProvider with following URI: MediaStore.<Audio,Video,Images,File>.Media.EXTERNAL_CONTENT_URI, depending on which data you want

2.3 How to get all files without MediaStore? (known ✔)

On this android version you only need the android.permission.WRITE_EXTERNAL_STORAGE, then you can directly list all files on the external storages via the File class. All you need to know are the available root paths from point 1

3. How to edit files on those storages? (known ✔)

Can be done directly via the File class if you have the above mentioned permission in your manifest.

----------------------------------------------

Android 4.4:

----------------------------------------------

This device is very specific, as it does not yet offer the Storage Access Framework but already limits the access to secondary storages!

1. How to find out all available local storages + find out the type (primary, secondary resp. internal, sd card, usb)? (partially known ✖)

Basically, this should be possible in the same way as on android < 4.4...

2.1 Which storages will be indexed via the MediaStore? (unknown ✖)

On this device only the primary storage will be indexed, correct?

2.2 How to get all files via the MediaStore? (known ✔)

Works the same way as it worked on android < 4.4...

2.3 How to get all files without MediaStore? (partially known ✖)

On the primary storage it works the same way as it did on android <4.4. I don't know how it works on this android version for the other local storages...

3. How to edit files on those storages? (partially known ✖)

Primary storages files will be editable via the File class. I don't know how to get reliable write access to other storages...

----------------------------------------------

Android >=5:

----------------------------------------------

1. How to find out all available local storages + find out the type (primary, secondary resp. internal, sd card, usb)? (partially known ✖)

Getting primary storage is possible as before. I don't know how to get a list of all other storages though. The manual way is to let the user choose the root directory of the secondary storage, sd card, usb stick like following:

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
context.startActivityForResult(intent, 1234);

And afterwards just remember the returned Uri and persist the Uri when getting the result from the Storage Access Framework:

public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == 1234)
    {
        if (resultCode == Activity.RESULT_OK)
        {
            // get uri
            Uri treeUri = data.getData();

            // persist permissions
            final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            getContentResolver().takePersistableUriPermission(treeUri, takeFlags);

            // remember the uri for having access to the storage
            // ...
        }
        return true;
    }
    return false;
}

I don't know how to find out the type (sd card, usb) of the directory the user selected though.

All files UNDER the root path will be readable and writeable via the DocumentFile class.

2.1 Which storages will be indexed via the MediaStore? (unknown ✖)

Only the primary I think. Correct?

2.2 How to get all files via the MediaStore? (known ✔)

Works as before...

2.3 How to get all files without MediaStore? (known ✔)

For the primary storage, it works as before as well (just via the File class), for the rest you HAVE to use the Uri for the corresponding storage that you got in point 1. Then you can use the DocumentFile class to get all files

3. How to edit files on those storages? (known ✔)

Primary storages files will be editable via the File class, the rest will be editable via the DocumentFile (with the help of the tree Uri from point 1).