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.
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).
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.
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.
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:
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
Based on Howards class I made some modifications to make it work on the Galaxy S3.
_
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With