Как получить программно путь к физической SD card на Android устройствах?

Например на Samsung Galaxy s2/s3 если использовать getExternalFilesDir то мы получаем путь вида /storage/sdcard0/Android/data/com.company.app/files/ когда как реальная физическая SD card находится на /mnt/extSdcard, а /storage/sdcard0 замаплена на внутреннюю память

На некоторых устройствах getExternalFilesDir возвращает нужный путь, но на многих поведение как выше.

Поделитесь кодом или соображением, как получать путь хотя бы к одной из физически установленных SD card.

android 2.3.3+
  • Вопрос задан
  • 7354 просмотра
Пригласить эксперта
Ответы на вопрос 2
ntkt
@ntkt
Потомственный рыцарь клавиатуры и паяльника
У андроида просто нет такого понятия как "реальная физическая SD-карта".
Всё, что Вы можете сделать -- это перебирать все точки монтирования из разных источников (вывод команды mount или /proc/mounts, файл vold.fstab в /system/etc и т.д.) и проверять их различными догадками вида:
-- заранее известные пути (типа Вашего /mnt/extSdcard)
-- путь содержит известную строку
-- ...
Все как-то так и мучаются.
Ответ написан
@Evgenij_Popovich
Использую команду mount. Решение найдено на stackoverflow

/**
     * Returns possible external sd card path. Solution taken from here
     * http://stackoverflow.com/a/13648873/527759
     * 
     * @return
     */
    public static Set<String> getExternalMounts() {
        final Set<String> out = new HashSet<String>();
        try {
            String reg = ".*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
            StringBuilder sb = new StringBuilder();
            try {
                final Process process = new ProcessBuilder().command("mount")
                        .redirectErrorStream(true).start();
                process.waitFor();
                final InputStream is = process.getInputStream();
                final byte[] buffer = new byte[1024];
                while (is.read(buffer) != -1) {
                    sb.append(new String(buffer));
                }
                is.close();
            } catch (final Exception e) {
                e.printStackTrace();
            }
            // parse output
            final String[] lines = sb.toString().split("\n");
            for (String line : lines) {
                if (!line.toLowerCase(Locale.ENGLISH).contains("asec")) {
                    if (line.matches(reg)) {
                        String[] parts = line.split(" ");
                        for (String part : parts) {
                            if (part.startsWith("/"))
                                if (!part.toLowerCase(Locale.ENGLISH).contains("vold")) {
                                    CommonUtils.debug(TAG, "Found path: " + part);
                                    out.add(part);
                                }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            error(TAG, ex);
        }
        return out;
    }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы