Check whether the SD card is available or not programmatically
Asked Answered
O

12

58

My app is working for mobiles which have an SD card only. So programmatically I want to check if the SD card is available or not and how to find the SD card free space. Is it possible?

If yes, how do I do it?

Olvan answered 15/9, 2011 at 10:14 Comment(1)
What does "SD card only" mean? Do you mean it has no internal memory? That's hard to imagine.Scuba
P
138
Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable();

if(isSDSupportedDevice && isSDPresent)
{
  // yes SD-card is present
}
else
{
 // Sorry
}
Pollypollyanna answered 15/9, 2011 at 10:16 Comment(11)
how to check the sdcard free memory?Olvan
but it return true if phone has inbuild storage..so not the correct answerLighting
On modern Android devices, external storage (known as "sdcard") can now be also internal storage, just separate. So yes, it is a good answer.Carrie
Also it's a good idea to check not only Environment.MEDIA_MOUNTED, but also Environment.MEDIA_MOUNTED_READ_ONLYPlasticizer
To determine if external storage is a SDCARD use the above in conjunction with: Environment.isExternalStorageRemovable()Poi
"External storage" is not necessarily an SD card. On many devices - most devices that I have seen recently - there is emulated "external" storage that is not an SD card (at least not a removable one). So this will give you a wrong answer. See developer.android.com/reference/android/os/… "Note: don't be confused by the word "external" here. This directory can better be thought as media/shared storage. ... it may also be implemented as built-in storage ..."Scuba
This returns true for a device that has no SD card and only internal memory.Slav
check this if phone has inbuild storage https://mcmap.net/q/328804/-check-whether-the-sd-card-is-available-or-not-programmaticallyBesprinkle
This is clearly a wrong answer in case of emulated external storage. Ideally Environment.isExternalStorageRemovable() should be used. You can also see Environment.isExternalStorageEmulated(). @Olvan you should not accept a partial answer.Selfdelusion
even though emulator has a SD card available on it in android studio, this test condition didn't return true.Retaliation
on samsung glaxy a52, after inserting sd card isSDPresent return true, but isSDSupportedDevice return false.Tooling
P
24

Accepted answer doesn't work for me

Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);

In case if device has a built-in storage, it returns true; My solution is that to check the external files directory count, if there is more than one, device has sdcard. It works and I tested it for several devices.

public static boolean hasRealRemovableSdCard(Context context) {
    return ContextCompat.getExternalFilesDirs(context, null).length >= 2;
}
Prau answered 6/3, 2017 at 10:22 Comment(3)
But if there is a slot in device and sd card is not inserted, it shows length as 2. The file array has null file. Anyway it is a best solution for me :)Interstate
@JemoMgebrishvili I tested it on Samsung J2 (API 22) 5.1 and works fine. Thank you so muchNathalienathan
ContextCompat.getExternalFilesDirs has ANR on some devicesQuoit
M
16

You can check if external removable sd card is available like this

public static boolean externalMemoryAvailable(Activity context) {
    File[] storages = ContextCompat.getExternalFilesDirs(context, null);
    if (storages.length > 1 && storages[0] != null && storages[1] != null)
        return true;
    else
        return false;

}

This works perfectly as i have tested it.

Mikesell answered 17/8, 2017 at 9:54 Comment(1)
I have tested it on Samsung A70s, with and without an external(removable) SD card, and in both cases, it's working fine. I have tried all the suggested solutions by others but this one worked correctly. Hopefully will work also for all devices. Thank you very much.Shaner
N
15

Use Environment.getExternalStorageState() as described in "Using the External Storage".

To get available space on external storage, use StatFs:

// do this only *after* you have checked external storage state:
File extdir = Environment.getExternalStorageDirectory();
File stats = new StatFs(extdir.getAbsolutePath());
int availableBytes = stats.getAvailableBlocks() * stats.getBlockSize();
Newhouse answered 15/9, 2011 at 10:16 Comment(0)
T
5

I wrote a little class for that checking the storage state. Maybe it's of some use for you.

import android.os.Environment;

/**
 * Checks the state of the external storage of the device.
 * 
 * @author kaolick
 */
public class StorageHelper
{
// Storage states
private boolean externalStorageAvailable, externalStorageWriteable;

/**
 * Checks the external storage's state and saves it in member attributes.
 */
private void checkStorage()
{
// Get the external storage's state
String state = Environment.getExternalStorageState();

if (state.equals(Environment.MEDIA_MOUNTED))
{
    // Storage is available and writeable
    externalStorageAvailable = externalStorageWriteable = true;
}
else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
{
    // Storage is only readable
    externalStorageAvailable = true;
    externalStorageWriteable = false;
}
else
{
    // Storage is neither readable nor writeable
    externalStorageAvailable = externalStorageWriteable = false;
}
}

/**
 * Checks the state of the external storage.
 * 
 * @return True if the external storage is available, false otherwise.
 */
public boolean isExternalStorageAvailable()
{
checkStorage();

return externalStorageAvailable;
}

/**
 * Checks the state of the external storage.
 * 
 * @return True if the external storage is writeable, false otherwise.
 */
public boolean isExternalStorageWriteable()
{
checkStorage();

return externalStorageWriteable;
}

/**
 * Checks the state of the external storage.
 * 
 * @return True if the external storage is available and writeable, false
 *         otherwise.
 */    
public boolean isExternalStorageAvailableAndWriteable()
{
checkStorage();

if (!externalStorageAvailable)
{
    return false;
}
else if (!externalStorageWriteable)
{
    return false;
}
else
{
    return true;
}
}
}
Trigeminal answered 12/7, 2013 at 9:55 Comment(5)
does this calss helps detect sd card availability ?Sturgill
@PankajNimgade This class helps you to check if external storage is available and/or writable. External storage can be an SD-card or built-in storage like in the nexus devices.Trigeminal
is it possible to check specifically for the "sdcard" ?, Thanks in advanceSturgill
@PankajNimgade Not that I know of. I would recommend to read about Internal and External storage here: developer.android.com/guide/topics/data/data-storage.htmlTrigeminal
been through that and several other documents, there is no specific difference made by google on "external storage available on device" and "sd card"....... :(Sturgill
R
4

I modified it such that if an SD card exists, it sets the path there. If not, it sets it at the internal directory.

Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
if(isSDPresent)
{
    path = theAct.getExternalCacheDir().getAbsolutePath() + "/GrammarFolder";
}
else
{
    path = theAct.getFilesDir() + "/GrammarFolder";
}
Recoverable answered 2/9, 2013 at 12:28 Comment(0)
M
3
 void updateExternalStorageState() {
     String state = Environment.getExternalStorageState();
     if (Environment.MEDIA_MOUNTED.equals(state)) {
        mExternalStorageAvailable = mExternalStorageWriteable = true;
     } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        mExternalStorageAvailable = true;
       mExternalStorageWriteable = false;
     } else {
       mExternalStorageAvailable = mExternalStorageWriteable = false;
}
handleExternalStorageState(mExternalStorageAvailable,
        mExternalStorageWriteable);
}
Mccahill answered 15/9, 2011 at 10:19 Comment(0)
B
2

This simple method is worked for me. Tested in all type of devices.

public boolean externalMemoryAvailable() {
    if (Environment.isExternalStorageRemovable()) {
      //device support sd card. We need to check sd card availability.
      String state = Environment.getExternalStorageState();
      return state.equals(Environment.MEDIA_MOUNTED) || state.equals(
          Environment.MEDIA_MOUNTED_READ_ONLY);
    } else {
      //device not support sd card. 
      return false;
    }
  }
Besprinkle answered 27/10, 2016 at 10:58 Comment(0)
P
2

Kotlin

fun Context.externalMemoryAvailable(): Boolean {
    val storages = ContextCompat.getExternalFilesDirs(this, null)
    return storages.size > 1 && storages[0] != null && storages[1] != null
}
Paradies answered 17/12, 2018 at 2:18 Comment(0)
S
1
  public static boolean hasSdCard(Context context) {

    File[] dirs = context.getExternalFilesDirs("");        
    if(dirs.length >= 2 && dirs[1]!=null){
        if(Environment.isExternalStorageRemovable(dirs[1])){ // Extra Check
            return true;
        }
     }
    return false;
   }
Sugared answered 6/11, 2019 at 17:25 Comment(0)
D
0

I created a class to check if the folder on the SD card is available or not:

public class GetFolderPath {

    static String folderPath;

    public static String getFolderPath(Context context) {
        if (isSdPresent() == true) {
            try {
                File sdPath = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/FolderName");
                if(!sdPath.exists()) {
                    sdPath.mkdirs();
                    folderPath = sdPath.getAbsolutePath();
                } else if (sdPath.exists()) {
                    folderPath = sdPath.getAbsolutePath();
                }
            }
            catch (Exception e) {

            }
            folderPath = Environment.getExternalStorageDirectory().getPath()+"/FolderName/";
        }
        else {
            try {
                File cacheDir=new File(context.getCacheDir(),"FolderName/");
                if(!cacheDir.exists()) {
                    cacheDir.mkdirs();
                    folderPath = cacheDir.getAbsolutePath();
                } else if (cacheDir.exists()) {
                    folderPath = cacheDir.getAbsolutePath();
                }
            }
            catch (Exception e){

            }
        }
        return folderPath;
    }

    public static boolean isSdPresent() {
        return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
    }
}
Doris answered 6/6, 2014 at 6:35 Comment(0)
M
0
** i fixed this with help of @Jemo Mgebrishvili answer** 

this works perfectly even if sd card is present and in the ejected state

 if (ContextCompat.getExternalFilesDirs(this, null).length >= 2) {
                File[] f = ContextCompat.getExternalFilesDirs(this, null);
                for (int i = 0; i < f.length; i++) {
                    File file = f[i];
                    if(file!=null && i ==1)
                    {
                        Log.d(TAG,file.getAbsolutePath()+ "external sd card  available");

                    }

                }
            } else {
                Log.d(TAG, " external sd card not available");

            }
Moradabad answered 22/11, 2018 at 10:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.