package com.door43.util; import android.os.Environment; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.StringTokenizer; /** * This class provides utilites for determine what storage is available to the app. * This is nessesary because android will not reliably determine the sd card. * see http://stackoverflow.com/questions/9340332/how-can-i-get-the-list-of-mounted-external-storage-of-android-device * */ public class StorageUtils { private static final String TAG = "StorageUtils"; public static class StorageInfo { public final String path; public final boolean readonly; public final boolean removable; public final int number; StorageInfo(String path, boolean readonly, boolean removable, int number) { this.path = path; this.readonly = readonly; this.removable = removable; this.number = number; } public String getDisplayName() { StringBuilder res = new StringBuilder(); if (!removable) { res.append("Internal SD card"); } else if (number > 1) { res.append("SD card " + number); } else { res.append("SD card"); } if (readonly) { res.append(" (Read only)"); } return res.toString(); } /** * Returns the name of the mount directory * @return */ public String getMountName() { String pieces[] = path.split("/"); return pieces[pieces.length-1]; } } public static List<StorageInfo> getStorageList() { List<StorageInfo> list = new ArrayList<StorageInfo>(); String def_path = Environment.getExternalStorageDirectory().getPath(); boolean def_path_removable = Environment.isExternalStorageRemovable(); String def_path_state = Environment.getExternalStorageState(); boolean def_path_available = def_path_state.equals(Environment.MEDIA_MOUNTED) || def_path_state.equals(Environment.MEDIA_MOUNTED_READ_ONLY); boolean def_path_readonly = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY); HashSet<String> paths = new HashSet<String>(); int cur_removable_number = 1; if (def_path_available) { paths.add(def_path); list.add(0, new StorageInfo(def_path, def_path_readonly, def_path_removable, def_path_removable ? cur_removable_number++ : -1)); } BufferedReader buf_reader = null; try { buf_reader = new BufferedReader(new FileReader("/proc/mounts")); String line; while ((line = buf_reader.readLine()) != null) { if (line.contains("vfat") || line.contains("/mnt")) { StringTokenizer tokens = new StringTokenizer(line, " "); String unused = tokens.nextToken(); //device String mount_point = tokens.nextToken(); //mount point if (paths.contains(mount_point)) { continue; } unused = tokens.nextToken(); //file system List<String> flags = Arrays.asList(tokens.nextToken().split(",")); //flags boolean readonly = flags.contains("ro"); if (line.contains("/dev/block/vold")) { if (!line.contains("/mnt/secure") && !line.contains("/mnt/asec") && !line.contains("/mnt/obb") && !line.contains("/dev/mapper") && !line.contains("tmpfs")) { paths.add(mount_point); list.add(new StorageInfo(mount_point, readonly, true, cur_removable_number++)); } } } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (buf_reader != null) { try { buf_reader.close(); } catch (IOException ex) {} } } return list; } /** * Returns the storage info for the removeable media if it exists * @return */ public static StorageInfo getRemoveableMediaDevice() { return getMountDevice("sdcard1"); } /** * Returns storage info for a mount device * @param name the name of the mount device * @return */ public static StorageInfo getMountDevice(String name) { List<StorageUtils.StorageInfo> storageList = getStorageList(); for(StorageUtils.StorageInfo info:storageList) { if(info.removable && info.getMountName().equals(name)) { return info; } } return null; } }