How to get actual size of mounted SD card in Andro

2019-02-19 08:01发布

问题:

I'm trying to find a way to find the total size and free space of a mounted SD card on a phone, from my research on SOF and on the Android devs site I was able to find the method getExternalStorageDirectory() but according to the Android API this returns a directory that is not necessarily external:

"Traditionally this is an SD card, but it may also be implemented as built-in storage in a device that is distinct from the protected internal storage and can be mounted as a filesystem on a computer."

So I gather from the way that is worded that the "external storage" directory can actually be apart of multiple physical storage devices (internal and external memory). And from my testing that's what I've found as the size that is being returned by using this method is around 1.5x the size of my actual SD card.

So my question is, is there a programmatical way to return the total size and available space just on the SD card? The phone itself can give me that information so I feel like there should be a way but I'm at a loss right now... any help would be appreciated!

EDIT: This is the code I'm currently using for total size

private long TotalSDMemory(){
    File path = Environment.getExternalStorageDirectory();
    StatFs stat = new StatFs(path.getAbsolutePath());
    long blockSize = stat.getBlockSize();
    long totalBlocks = stat.getBlockCount();
    long totalSpace = totalBlocks * blockSize;
    Log.d(TAG,"Size of total SD Memory: "+totalSpace);
    Log.d(TAG, "External storage emulated: "+Environment.isExternalStorageEmulated());
    return totalSpace;
}

Edit(2): I didn't know this mattered but I have a Samsung Galaxy S3 which is what I am using to test the code, apparently Samsung has a different file structure for their external memory. Here is a link that should help anyone else get the correct size: Get size of SD card in Samsung phones

回答1:

Yes, there is a way.

StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long sdAvailSize = (long)stat.getAvailableBlocks()
               * (long)stat.getBlockSize();
//One binary gigabyte equals 1,073,741,824 bytes.
long gigaAvailable = sdAvailSize / 1073741824;

Got that from here: How can I check how much free space an SD card mounted on an Android device has?

Concerning your question about getting total size look here: Getting all the total and available space on Android


Edit:

Marcelo Filho has pointed out that this method is deprecated in API 18 (KitKat).

Google suggests to use getAvailableBlocksLong () and getBlockCountLong () instead. Both methods will return a long value and not a double.

Hint:

Kikiwa has pointed out that the datatype long should be used with these -now deprecated - methods, otherwise you may get negative values if the filesize is too large.



回答2:

public String[] getSize() throws IOException {
    String memory="";
    Process p = Runtime.getRuntime().exec("df /mnt/sdcard");
    InputStream is =p.getInputStream();
    int by=-1;
    while((by=is.read())!=-1) {
        memory+=new String(new byte[]{(byte)by});
    }
    for (String df:memory.split("/n")) {
        if(df.startsWith("/mnt/sdcard")) {
            String[] par = df.split(" ");
            List<String> pp=new ArrayList<String>();
            for(String pa:par) {
                if(!pa.isEmpty()) {
                    pp.add(pa);
                }
            }
            return pp.toArray(new String[pp.size()]);

        }
    }
    return null;
}

getSize()[0] is /mnt/sdcard. getSize()[1] is size of sd (example 12.0G), getSize()[2] is used, [3] is free, [4] is blksize

Or:

new File("/sdcard/").getFreeSpace() - bytes of free in long
new File("/sdcard/").getTotalSpace() - size of sd