Как определить, находится ли файл на запоминающем устройстве USB?

Учитывая File или Uri, как я могу надежно определить, находится ли файл на запоминающем устройстве USB, подключенном к USB-порту телефона?

К моему тестовому телефону, Samsung Galaxy S7 Edge, подключено запоминающее устройство USB, внутренняя (физическая) карта micro SD и внутреннее хранилище. Когда я запрашиваю Context.getExternalCacheDirs(), я вижу все три из них:

/storage/emulated/0/Android/data/...
/storage/A2B3-15F3/Android/data/...
/storage/3535-3038/Android/data/...

Как определить, какой из них является запоминающим устройством USB? (Кстати, это A2B3-15F3).


Исследовательская работа

Я просмотрел этот ответ (метод StorageHelper.resolveType()), но, как видите, путь к смонтированному файлу устройства не содержит строка «usb».

Затем я попытался использовать службу StorageManager. С указанными выше устройствами мы можем получить StorageVolume`, используя:

StorageManager storageManager = context.getSystemService(StorageManager.class);
StorageVolume volume = storageManager.getStorageVolume(context.getExternalCacheDirs()[1]);

Здесь все стало немного странно. StorageVolumeдокументация API и моя локальная копия файла в исходники Android 25 не очень помогают мне, но когда я выполняю приведенный выше код в отладчике Android Studio, объект содержит поле mSubSystem, которое описывает три устройства выше как «предохранитель», «usb» и «sd " соответственно. Вот пример:

Снимок экрана отладчика Android Studio, показывающий StorageVolume для запоминающего устройства USB

Почему я вижу эту информацию в отладчике, а не в исходнике? Может ли это поле быть специфичным для дистрибутива Android для этого конкретного телефона?


person NickG    schedule 17.05.2017    source источник


Ответы (2)


Environment.getExternalStorageDirectory() вернет путь к точке подключения SD-карты. USB-накопитель поддерживается очень немногими устройствами (теми, которые поддерживают режим USB-хоста для внешнего хранилища). Он будет смонтирован где-то под /mnt, но точное местоположение будет другим. Вам потребуется использовать Android NDK для опроса и перебора подключенных устройств, чтобы найти нужное. Написание логики под NDK и запрос внутри /mnt — надежный маршрут.

Если вы действительно хотите попробовать на стороне Java, попробуйте следующий код, если он работает для вас:

public String getUSBStoragepath() {
    try {
        Runtime runtime = Runtime.getRuntime();
        Process proc = runtime.exec("mount");
        InputStream input_stream = proc.getInputStream();
        InputStreamReader isr = new InputStreamReader(input_stream);
        String line;
        String[] paths_list = new String[10];
        int i = 0;
        int available = 0;

        BufferedReader buffer_reader = new BufferedReader(isr);
        while ((line = buffer_reader.readLine()) != null) {
            String mount = new String();
            if (line.contains("secure"))
                continue;
            if (line.contains("asec"))
                continue;

            if (line.contains("fat")) {// TF card
                String columns[] = line.split(" ");
                if (columns != null && columns.length > 1) {
                    mount = mount.concat(columns[1] + "/requiredfiles");

                    paths_list[i] = mount;
                    i++;

                    // check directory is exist or not
                    File dir = new File(mount);
                    if (dir.exists() && dir.isDirectory()) {
                        // do something here

                        available = 1;
                        final_path = mount;
                        break;
                    } else {

                    }
                }
            }
        }
        if (available == 1) {

        } else if (available == 0) {
            final_path = paths_list[0];
        }

    } catch (Exception e) {

    }
    return final_path;
}

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

person TheWaterProgrammer    schedule 17.05.2017

Вы можете проверить, подключен ли USB-накопитель к телефону через USBManager, список подключенных USB-устройств, а затем проверить USBInterface, если его класс — USB_CLASS_MASS_STORAGE. Затем попросите пользователя отключить USB-накопитель, сохранить путь к SD-карте и попросить пользователя повторно подключить USB. Остальные каталоги будут USB-путем.

person user3205958    schedule 06.02.2018
comment
Это не дает ответа на вопрос. Вы можете выполнить поиск похожих вопросов или обратиться к связанным и связанным вопросам в правой части страницы, чтобы найти ответ. Если у вас есть похожий, но другой вопрос, задайте новый вопрос и включите ссылку на этот вопрос, чтобы обеспечить контекст. См.: Задавайте вопросы, получайте ответы, не отвлекайтесь - person Machavity♦; 06.02.2018