Как я могу получить список смонтированного внешнего хранилища Android-устройства

Здесь мы разрабатываем приложение для Android для ящика для Android. Как я могу получить список подключенного внешнего хранилища, например USB stick, SDCARD and SATA HDD.

Ответ 1

Я использую /proc/mounts файл, чтобы получить список доступных параметров хранения

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();
        }
    }

    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;
            Log.d(TAG, "/proc/mounts");
            while ((line = buf_reader.readLine()) != null) {
                Log.d(TAG, line);
                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 ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (buf_reader != null) {
                try {
                    buf_reader.close();
                } catch (IOException ex) {}
            }
        }
        return list;
    }
}

Ответ 2

Чтобы получить все доступные внешние папки хранения (включая SD-карты), вы можете использовать это:

File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null);

Чтобы перейти в "корень" каждого внешнего хранилища (тот, который является реальным путем установки пути к папке), вы можете использовать эту функцию, которую я сделал:

  /** Given any file/folder inside an sd card, this will return the path of the sd card */
  private static String getRootOfInnerSdCardFolder(File file)
    {
    if(file==null)
      return null;
    final long totalSpace=file.getTotalSpace();
    while(true)
      {
      final File parentFile=file.getParentFile();
      if(parentFile==null||parentFile.getTotalSpace()!=totalSpace)
        return file.getAbsolutePath();
      file=parentFile;
      }
    }

Ответ 3

Environment.getExternalStorageState() возвращает путь к внутренней точке монтирования SD, например, "/mnt/sdcard"

Нет, Environment.getExternalStorageDirectory() относится к тому, что изготовитель устройства считается "внешним хранилищем". На некоторых устройствах это съемный носитель, например SD-карта. На некоторых устройствах это часть вспышки на устройстве. Здесь "внешнее хранилище" означает "материал, доступный через режим USB Mass Storage при установке на хост-машине", по крайней мере для Android 1.x и 2.x.

Но вопрос о внешней SD. Как получить путь, например "/mnt/sdcard/external_sd" (он может отличаться от устройства к устройству)?

Android не имеет понятия "внешний SD", кроме внешнего хранилища, как описано выше.

Если производитель устройства выбрал внешнюю память на борту, а также имеет SD-карту, вам необходимо связаться с этим производителем, чтобы определить, можете ли вы использовать SD-карту (не гарантируется), и что правила для его использования, например, какой путь использовать для него.

Попробуйте следующее:

Manifest.xml:

<receiver android:name=".MyReceiver">
    <intent-filter>
         <action android:name="android.intent.action.ums_connected" />
     </intent-filter>
  </receiver>

Myreceiver:

public class MyReceiver extends BroadcastReceiver{
if (intent.getAction().equalsIgnoreCase(
        "android.intent.action.UMS_CONNECTED")) {...}
}

Ответ 4

Другая альтернатива.

Сначала получите все внешние файлы dirs

File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null);

Затем вызовите эту функцию для каждой из папок

private static String getRootOfExternalStorage(File file)
{
    if (file == null)
        return null;
    String path = file.getAbsolutePath();
    return path.replaceAll("/Android/data/" + getPackageName() + "/files", "");
}

Ответ 5

Вы можете использовать getExternalStorageDirectory() для получения каталога внешнего хранилища. Документация дает хорошее объяснение ее использования http://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory%28%29

Для USB-устройств вам, вероятно, придется изучить класс UsbManager или более android.hardware.usb http://developer.android.com/reference/android/hardware/usb/UsbManager.html

Ответ 6

Я сейчас эта тема старая, но это может помочь. вы должны использовать этот метод.

System.getenv();

см. проект Environment3 для доступа ко всем хранилищам, подключенным к вашему устройству.

https://github.com/omidfaraji/Environment3