Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access removable storage on Android devices?

I am looking for a way to detect and access removable sd cards on a variety of Android devices (Samsung, Motorola, LG, Sony, HTC).

I also need to be compatible with 2.2 so Environment.isExternalStorageRemovable() is unavailable for me.

Motorola has its own library, and for Samsung I can detect the existence of /external_sd/

I have no clue for the rest of them. For example, I have seen a /_ExternalSD/ on some LG's but it the directory remains even when the SD is removed.

A bonus question: will the ACTION_MEDIA_MOUNTED intent be broadcast for any of them

Any hint on this would be very helpful.

like image 982
znat Avatar asked Apr 23 '12 14:04

znat


People also ask

Can you connect external hard drive to Samsung phone?

To connect a USB memory card or external storage, plug the USB connector (USB Type-C) to the USB power adaptor of the device, followed by USB memory/external HDD into the USB connector (USB Type-C).

How can I use OTG on my phone?

Users just need to plug in the drive and it will enable them to transfer files between the devices. However, some external hard drives might not work with the OTG cable, especially the ones that draw power from the phone. The drives need to be in FAT32 or exFAT file format to work with OTG.

How do I find my USB drive?

PC users should look in File Explorer, also on the left-hand side menu. You should see the drive name and its volume letter appear under "This PC" near your other storage volumes.


2 Answers

Here's a class I use to find all sdcards on a device; built in and removable. I've been using it on Ice Cream Sandwich, but it should work at 2x levels.

public class GetRemovableDevice {

private final static String TAG = "GetRemoveableDevice";

public GetRemovableDevice() {
}

public static String[] getDirectories() {
    MyLog.d(TAG, "getStorageDirectories");
    File tempFile;
    String[] directories = null;
    String[] splits;
    ArrayList<String> arrayList = new ArrayList<String>();
    BufferedReader bufferedReader = null;
    String lineRead;

    try {
        arrayList.clear(); // redundant, but what the hey
        bufferedReader = new BufferedReader(new FileReader("/proc/mounts"));

        while ((lineRead = bufferedReader.readLine()) != null) {
            MyLog.d(TAG, "lineRead: " + lineRead);
            splits = lineRead.split(" ");

            // System external storage
            if (splits[1].equals(Environment.getExternalStorageDirectory()
                    .getPath())) {
                arrayList.add(splits[1]);
                MyLog.d(TAG, "gesd split 1: " + splits[1]);
                continue;
            }

            // skip if not external storage device
            if (!splits[0].contains("/dev/block/")) {
                continue;
            }

            // skip if mtdblock device

            if (splits[0].contains("/dev/block/mtdblock")) {
                continue;
            }

            // skip if not in /mnt node

            if (!splits[1].contains("/mnt")) {
                continue;
            }

            // skip these names

            if (splits[1].contains("/secure")) {
                continue;
            }

            if (splits[1].contains("/mnt/asec")) {
                continue;
            }

            // Eliminate if not a directory or fully accessible
            tempFile = new File(splits[1]);
            if (!tempFile.exists()) {
                continue;
            }
            if (!tempFile.isDirectory()) {
                continue;
            }
            if (!tempFile.canRead()) {
                continue;
            }
            if (!tempFile.canWrite()) {
                continue;
            }

            // Met all the criteria, assume sdcard
            arrayList.add(splits[1]);
        }

    } catch (FileNotFoundException e) {
    } catch (IOException e) {
    } finally {
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException e) {
            }
        }
    }

    // Send list back to caller

    if (arrayList.size() == 0) {
        arrayList.add("sdcard not found");
    }
    directories = new String[arrayList.size()];
    for (int i = 0; i < arrayList.size(); i++) {
        directories[i] = arrayList.get(i);
    }
    return directories;
}

}

The MyLog.d is a trace class that expands Log.d - it can be dropped.

The class reads /proc/mounts/ and:

  1. checks to see if the path name is the internal sdcard directory
  2. checks to see if its a block device
  3. skips mtdblock devices
  4. skips anything that is not mounted
  5. skips secure and asec directories
  6. makes sure it exists, is a directory, and read/write accessible

If all this is matched, it assumes that you have an sdcard and adds the path to the array list. It returns a string array of path names.

To call the getDirectories function, code something similar to:

String[] sdcardDirectories = GetRemoveableDevice.getDirectories();

The paths returned can be used to create a user selection list, scan for a file, or whatever.

Finally, here's two lines of MyLog.d from an emulator test (second line is the emulator sdcard):

09-19 15:57:12.511: D/GetRemoveableDevice(651): lineRead: /dev/block/mtdblock2 /cache yaffs2 rw,nosuid,nodev 0 0

09-19 15:57:12.511: D/GetRemoveableDevice(651): lineRead: /dev/block/vold/179:0 /mnt/sdcard vfat rw,dirsync,nosuid,nodev,noexec,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0

like image 187
Howard Hodson Avatar answered Oct 31 '22 05:10

Howard Hodson


Based on Howards class I made some modifications to make it work on the Galaxy S3.

  1. Environment.getExternalStorageDirectory() returns internal storage on the S3.
  2. Removable storage is not necessarily mounted under /mnt
  3. Removable media must have vfat filesystem

_

public static String getDirectory() {
        Log.d(TAG, "getStorageDirectories");
        File tempFile;
        String[] splits;
        ArrayList<String> arrayList = new ArrayList<String>();
        BufferedReader bufferedReader = null;
        String lineRead;

        try {
            arrayList.clear(); // redundant, but what the hey
            bufferedReader = new BufferedReader(new FileReader("/proc/mounts"));

            while ((lineRead = bufferedReader.readLine()) != null) {
                Log.d(TAG, "lineRead: " + lineRead);
                splits = lineRead.split(" ");

                // skip if not external storage device
                if (!splits[0].contains("/dev/block/")) {
                    continue;
                }

                // skip if mtdblock device
                if (splits[0].contains("/dev/block/mtdblock")) {
                    continue;
                }

                // skip if not in vfat node
                if (!splits[2].contains("vfat")) {
                    continue;
                }

                // skip these names
                if (splits[1].contains("/secure")) {
                    continue;
                }

                if (splits[1].contains("/mnt/asec")) {
                    continue;
                }

                // Eliminate if not a directory or fully accessible
                tempFile = new File(splits[1]);
                if (!tempFile.exists()) {
                    continue;
                }
                if (!tempFile.isDirectory()) {
                    continue;
                }
                if (!tempFile.canRead()) {
                    continue;
                }
                if (!tempFile.canWrite()) {
                    continue;
                }

                // Met all the criteria, assume sdcard
                return splits[1];
            }

        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                }
            }
        }

        return null;
    }
like image 2
tmanthey Avatar answered Oct 31 '22 04:10

tmanthey