Есть ли в Android 2.x документированный способ проверки содержимого нескольких SD-карт? - PullRequest
5 голосов
/ 27 мая 2011

Некоторые планшеты Android 2.x, такие как HTC Flyer и Samsung Galaxy Tab, поддерживают как внутреннюю память планшета, так и внешнюю SD-карту.Например, на моем Flyer /sdcard и /sdcard2 являются отдельными, причем первый представляет «внутреннее хранилище» планшета.

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

Одним из решений является простое сканирование /sdcard* жесткого кода в приложении, но это делаетПредположение, что все устройства будут использовать это в качестве схемы именования, и я не считаю это безопасным предположением.

Существует ли документированный способ сканирования и использования нескольких SD-карт / мест хранения в Android 2.x?

Моя цель на самом деле найти все аудиокниги на планшете, поэтому я бы хотел найти и использовать все /sdcard*/Audiobooks каким-либо задокументированным способом.

Ответы [ 2 ]

3 голосов
/ 27 мая 2011

Обычно вторая SD-карта монтируется внутри первой.

Вот что я имею в виду:

  • Первая SDCard установлена ​​в /mnt/sdcard.

  • Вторая SDCard установлена ​​в /mnt/sdcard/external_sd

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

Это недокументированное поведение. Но Galaxy Tab ведет себя именно так. Я предполагаю, что это потому, что нет официальной поддержки Android API (т.е. нет специальной функции в классе Environment) для нескольких внешних хранилищ.

1 голос
/ 18 сентября 2013

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

Работает правильно на всех моих устройствах.

private static final Pattern DIR_SEPORATOR = Pattern.compile("/");

/**
 * Raturns all available SD-Cards in the system (include emulated)
 *
 * Warning: Hack! Based on Android source code of version 4.3 (API 18)
 * Because there is no standart way to get it.
 * TODO: Test on future Android versions 4.4+
 *
 * @return paths to all available SD-Cards in the system (include emulated)
 */
public static String[] getStorageDirectories()
{
    // Final set of paths
    final Set<String> rv = new HashSet<String>();
    // Primary physical SD-CARD (not emulated)
    final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
    // All Secondary SD-CARDs (all exclude primary) separated by ":"
    final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
    // Primary emulated SD-CARD
    final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
    if(TextUtils.isEmpty(rawEmulatedStorageTarget))
    {
        // Device has physical external storage; use plain paths.
        if(TextUtils.isEmpty(rawExternalStorage))
        {
            // EXTERNAL_STORAGE undefined; falling back to default.
            rv.add("/storage/sdcard0");
        }
        else
        {
            rv.add(rawExternalStorage);
        }
    }
    else
    {
        // Device has emulated storage; external storage paths should have
        // userId burned into them.
        final String rawUserId;
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
        {
            rawUserId = "";
        }
        else
        {
            final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
            final String[] folders = DIR_SEPORATOR.split(path);
            final String lastFolder = folders[folders.length - 1];
            boolean isDigit = false;
            try
            {
                Integer.valueOf(lastFolder);
                isDigit = true;
            }
            catch(NumberFormatException ignored)
            {
            }
            rawUserId = isDigit ? lastFolder : "";
        }
        // /storage/emulated/0[1,2,...]
        if(TextUtils.isEmpty(rawUserId))
        {
            rv.add(rawEmulatedStorageTarget);
        }
        else
        {
            rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
        }
    }
    // Add all secondary storages
    if(!TextUtils.isEmpty(rawSecondaryStoragesStr))
    {
        // All Secondary SD-CARDs splited into array
        final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
        Collections.addAll(rv, rawSecondaryStorages);
    }
    return rv.toArray(new String[rv.size()]);
}
...