Android 4.4+: проверьте, находится ли путь во вторичном хранилище

Мое приложение должно проверять, находится ли определенная папка во вторичном хранилище, когда версия Android 4.4+.

Я использую это:

private boolean isPathOnSecondaryStorage(String path) {
    boolean res=false;
    String secondaryStorage=System.getenv("SECONDARY_STORAGE");
    String[] secondaryPaths=secondaryStorage.split(":");
    for (int i=0;i<secondaryPaths.length;i++) {
        String secondaryPath=secondaryPaths[i].trim();
        if (path.contains(secondaryPath)) {
            res=true;
        }
    }
    return res;
}

Обратите внимание, что:

  • путь выбирается пользователем с помощью действия выбора файла, начиная с /mnt

  • приложение хочет проверить, что монтируется как обычно, например, когда в его слот вставлена ​​внешняя SD-карта

Поэтому я спрашиваю, всегда ли вышеупомянутый код сможет определить, когда путь находится на вторичном хранилище, или вместо этого на некоторых устройствах он может найти странные точки монтирования, отличные от /mnt (Android 4.4+).


person P5music    schedule 12.08.2014    source источник


Ответы (1)


Вот мое текущее решение. Не идеально, но должно работать.

/**
 * Uses the Environmental variable "SECONDARY_STORAGE" to locate a removable micro sdcard
 * 
 * @return  the primary secondary storage directory or
 *          {@code null} if there is no removable storage
 */
public static File getRemovableStorage() {
    final String value = System.getenv("SECONDARY_STORAGE");
    if (!TextUtils.isEmpty(value)) {
        final String[] paths = value.split(":");
        for (String path : paths) {
            File file = new File(path);
            if (file.isDirectory()) {
                return file;
            }
        }
    }
    return null;
}

/**
 * Checks if a file is on the removable SD card.
 * 
 * @see {@link Environment#isExternalStorageRemovable()}
 * @param file a {@link File}
 * @return {@code true} if file is on a removable micro SD card, {@code false} otherwise
 */
public static boolean isFileOnRemovableStorage(File file) {
    final File microSD = getRemovableStorage();
    if (microSD != null) {
        String canonicalPath;
        try {
            canonicalPath = file.getCanonicalPath();
            if (canonicalPath.startsWith(microSD.getAbsolutePath())) {
                return true;
            }
        } catch (IOException e) {
        }
    }
    return false;
}
person Jared Rummler    schedule 12.08.2014
comment
Будет ли getCanonicalPath() всегда возвращать путь, начинающийся с «/mnt»? Это очень важно. - person P5music; 12.08.2014
comment
getCanonicalPath() будет следовать любым символическим ссылкам, поэтому, если истинный путь к вторичному хранилищу не начинается с /mnt, ответ будет отрицательным. Это не имеет значения, поскольку вы больше нигде не будете использовать getCanonicalPath(). - person Jared Rummler; 13.08.2014
comment
На основе for (String path : paths) { File file = new File(path); if (file.isDirectory()) { return file; } } Почему вы можете убедиться, что первым элементом является съемная SD-карта? Спасибо. - person Hsin-Hsiang; 09.03.2015
comment
Я вспомнил, что это решение работало раньше, но сегодня я снова протестировал его на ASUS_Z00LDD, версия Android 6.0.1 и не работает. System.getenv("SECONDARY_STORAGE") приведет только к:/storage/sdcard1, но при вызове file.isDirectory() он не распознает его как каталог. Также реальный путь к SD-карте /storage/3FBF-1DF5/ - person HendraWD; 30.08.2017