How to List all Internal and External Android Storage

How to List all Internal and External Android Storage

Android Storage Manager is the system service which provides the functionality to list and access the all Storage Volume of an Android Device. We always required to save and read the files from Internal and External storage depending on the app requirement but accessing that SDCARD is sometimes difficult. So in this tutorial, we will explore the way to how to access the storage volume using Storage Manager as well as other methods.

Let’s create a sample project to go step wise step in this article.

Create an instance of Storage Manager system Service in Android

First of all, we are going to find the way how to list all SDCARD using the Storage Manager and Storage Volume system service. So let’s create the instance of Storage Manager system service as given below.

Java

StorageManager storageManager= 
(StorageManager) this.getSystemService(Context.STORAGE_SERVICE);

Kotlin

var storageManager:StorageManager = 
this.getSystemService(Context.STORAGE_SERVICE) as StorageManager

Here in above code, this is either context or activity from which you are creating the instance of the Storage Manager.

List the all Storage Volume

To get the list of all Internal and External mount point in android we have to call the getStorageVolumes method like given below. The getStorageVolumes method returns the list of all available SDCARD or storage.

Java

//get the list of all storage Volume
            List<StorageVolume> storageVolumeList=storageManager.getStorageVolumes();

Kotlin

//List storage Volume
var storageVolumeList:List<StorageVolume> =  storageManager.storageVolumes

Here, it is important to update you that as these methods introduced from Android API level 24. So you have to add the if condition to check the API level of the device on which this application is running. For the device which is lower than the API level 24, we can use the older method.

Java

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            //get the list of all storage Volume
            List<StorageVolume> storageVolumeList=storageManager.getStorageVolumes();
}
else
{
File storageFir = Environment.getExternalStorageDirectory();
            if (storageFir.list() != null) {
                Log.d(LOG_TAG,"List"+ storageFir.list().toString());
            }
}

Kotlin

val storageManager:StorageManager = this.getSystemService(Context.STORAGE_SERVICE) as StorageManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
        var storageVolumeList:List<StorageVolume> =  storageManager.storageVolumes
        } else {
            var storage:File=Environment.getExternalStorageDirectory()
        }

Permission Required for the Android Storage Manager

There are many ways to get the access to the Storage, which you can decide depending on your requirements.

You can get the access to the particular directory by creating the access intent for the respective directory as given below. It is a recommended method to get the access. Because, you are asking the permission for the directory, not entire storage.  So the user has confidence in you.  It is because you are asking the permission according to the user action and he will know well why you are asking the permission.

For example, using below code we can get the access from the user to access the DIRECTORY_PICTURES.

Intent fileIntent=storageVolumeList.get(i).createAccessIntent(Environment.DIRECTORY_PICTURES);
                    startActivityForResult(fileIntent,PERMISSION_PICTURE_REQUEST_CODE);}
  • fileIntent is the intent returned by createAccessIntent.
  • The second parameter is the request code to identify the same inside onActivityResult method you can declare the same as given below.
    public static int PERMISSION_PICTURE_REQUEST_CODE=101;

Above code will return the result in the onActivityResults method. It will return the intent that we can use to retrieve the Uri of the Directory as given below.

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==PERMISSION_PICTURE_REQUEST_CODE && resultCode==RESULT_OK){
           
            if(data!=null){
              Uri uri=  data.getData();
                Log.d(LOG_TAG,"Uri:"+uri);
            }
        }
    }

Alternatively, you can also ask for permission on the whole directory using Android standard permission method like given below.

if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);

Further, you can use the Storage Access Framework to access the Storage files.

List Path of Internal and External Storage Location

If we want to access the internal and external storage location. Then we must have location or mount point of the respective storage.

We can call the getExternalStorageDirectory method for getting the location of primary shared/external storage.

Environment.getExternalStorageDirectory().toString()

To get the all mount point directory we can just create a simple method like below and it will give all mount.

StorageManager storageManager=
 (StorageManager) getSystemService(Context.STORAGE_SERVICE);
            try {
              String[] volumes= (String[]) storageManager.getClass()
                      .getMethod("getVolumePaths", new Class[0])
.invoke(storageManager, new Object[0]);
                for(int i=0;i<volumes.length;i++)
                Log.d(LOG_TAG,volumes[i].toString());
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }

If we want to get the location of the shared directory like Download, Picture, etc then we can use the code as given below.

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)

As we know there is maybe a possibility of that external storage can be removed by the user. So we must check the state of the storage before accessing/using the storage.

Environment.getExternalStorageState()

Further, if we want to check the state of the all mount point by location then we can use the code as given below.

String[] volumes= (String[]) storageManager.getClass()
                      .getMethod("getVolumePaths", new Class[0]).invoke(storageManager, new Object[0]);
               for(int i=0;i<volumes.length;i++) {
                   Log.d(LOG_TAG, volumes[i].toString());
                   File file=new File(volumes[i].toString());
                   Log.d(LOG_TAG,"Status of the Media:"+Environment.getExternalStorageState(file));
               }

Check the disk space of the storage

If you want to write something on the device then you must want to check the space of the respective storage.

So for checking the available storage space of the mount, we can use the method given as below. In short, create a file for the respective mount point and call the file.getFreeSpace method and file.getTotalSpace

String[] volumes= (String[]) storageManager.getClass()
                      .getMethod("getVolumePaths", new Class[0]).invoke(storageManager, new Object[0]);
               for(int i=0;i<volumes.length;i++) {
                   Log.d(LOG_TAG, volumes[i].toString());
                   File file=new File(volumes[i].toString());
                   Log.d(LOG_TAG, "Free Space:"+file.getFreeSpace()+"Total Space:" +
                   file.getTotalSpace());
                   Log.d(LOG_TAG,"Status of the Media:"+Environment.getExternalStorageState(file));
               }

The output of the above method is in the byte. So if you want to convert it human readable format then you can create the method by putting the logic like below.

if (size >= 1024*1024*1024) {
            fileUnit = "GB";
             fileDisplaySize=df.format((((size / 1024) / 1024)/1024.00))+ fileUnit;

        }
       else if (size >= 1024*1024) {
            fileUnit = "MB";
            fileDisplaySize=df.format((((size / 1024) / 1024.00)))+ fileUnit;

        }else {
            fileUnit = "KB";
            fileDisplaySize = df.format(((size / 1024.00))) +fileUnit;
        }

 

 

Get Email Updates!

Signup now receive an email once I publish new content. I will never give away, trade or sell your email address. You can unsubscribe at any time.

Join 911 other subscribers

Leave a Reply

Close Menu