Как смонтировать USB-накопитель на Android Things?

Я пытаюсь прочитать файлы с USB-накопителя для приложения Android Things на Raspberry Pi. Я могу сканировать список подключенных устройств следующим образом:

public static List<File> ScanForFiles(Context context){
    ArrayList<File> files = new ArrayList<>();
    try{
        BufferedReader reader = new BufferedReader(new FileReader("/proc/self/mountinfo"));
        String line;
        while ((line = reader.readLine()) != null) {
            String[] columns = line.split(" ");
            Log.i(TAG, "Mounted: " + columns[4]);
            //files.addAll(getListFiles(new File(columns[4])));
        }
    } catch (Exception ex){
        ex.printStackTrace();
    }

    printFileInformation("/proc/partitions");

    return files;
}

private static void printFileInformation(String fileName){
    Log.i("TitanTV", "Reading contents of " + fileName);

    try{
        BufferedReader reader = new BufferedReader(new FileReader(fileName));
        String line;
        while ((line = reader.readLine()) != null){
            Log.i("TitanTV", line);
        }
    } catch (Exception ex){
        ex.printStackTrace();
    }
}

Что отображает следующий вывод:

I: Mounted: /
I: Mounted: /dev
I: Mounted: /dev
I: Mounted: /dev/pts
I: Mounted: /dev/memcg
I: Mounted: /dev/cpuctl
I: Mounted: /proc
I: Mounted: /sys
I: Mounted: /sys/fs/selinux
I: Mounted: /sys/fs/pstore
I: Mounted: /acct
I: Mounted: /mnt
I: Mounted: /mnt/runtime/default/emulated
I: Mounted: /mnt/runtime/read/emulated
I: Mounted: /mnt/runtime/write/emulated
I: Mounted: /config
I: Mounted: /data
I: Mounted: /oem
I: Mounted: /gapps
I: Mounted: /storage
I: Mounted: /storage/emulated
I: Mounted: /storage/self
I: Reading contents of /proc/partitions
I: major minor  #blocks  name
I:    1        0       8192 ram0
I:    1        1       8192 ram1
I:    1        2       8192 ram2
I:    1        3       8192 ram3
I:    1        4       8192 ram4
I:    1        5       8192 ram5
I:    1        6       8192 ram6
I:    1        7       8192 ram7
I:    1        8       8192 ram8
I:    1        9       8192 ram9
I:    1       10       8192 ram10
I:    1       11       8192 ram11
I:    1       12       8192 ram12
I:    1       13       8192 ram13
I:    1       14       8192 ram14
I:    1       15       8192 ram15
I:  179        0    7761920 mmcblk0
I:  179        1      65536 mmcblk0p1
I:  179        2       1024 mmcblk0p2
I:  179        3       1024 mmcblk0p3
I:  179        4      32768 mmcblk0p4
I:  179        5      32768 mmcblk0p5
I:  179        6     524288 mmcblk0p6
I:  179        7     524288 mmcblk0p7
I:  179        8         64 mmcblk0p8
I:  179        9         64 mmcblk0p9
I:  179       10       1024 mmcblk0p10
I:  179       11      32768 mmcblk0p11
I:  179       12      32768 mmcblk0p12
I:  179       13     262144 mmcblk0p13
I:  179       14     262144 mmcblk0p14
I:  179       15    2683736 mmcblk0p15
I:    8        0    7847935 sda
I:    8        1    7845888 sda1

Тем не менее, мой флэш-накопитель не является исключением из списка. Так что я думаю, мне нужно как-то смонтировать его. Как смонтировать флешку и получить доступ к файлам на ней?


person Chris Stillwell    schedule 26.02.2017    source источник


Ответы (4)


РЕШЕНИЕ ТОЛЬКО ADB

Похоже, что на данный момент USB-накопители не монтируются автоматически. Чтобы заставить ваш код работать, мне пришлось смонтировать его вручную.

Как видите (из /proc/partitions) в разделе /proc USB-накопитель определяется как sda.

Монтаж ADB

  • Создайте каталог для монтирования

    mkdir /mnt/usb
    
  • Установите устройство

    mount -t vfat -o rw /dev/block/sda1 /mnt/usb
    

Теперь вы сможете просматривать (и управлять) файлами на USB-накопителе как через ADB, так и из приложения (/mnt/usb также будет регистрироваться).

person Onik    schedule 26.02.2017
comment
Правильно, вплоть до предположения, что вы можете сделать это из приложения, которое глубоко ошибается как в ожидании, так и в методе - su нельзя получить, поскольку даже когда оно работает (здесь маловероятно!), оно применяется только к запущенному подпроцессу, а не к процесс запроса. - person Chris Stratton; 08.03.2018
comment
@Chris Stratton, su нельзя получить, даже если он работает (здесь маловероятно!) Почему это так? Вы listed system/xbin для любой из версий Android Things? su был отправлен для самой первой предварительной версии для разработчиков... - person Onik; 08.03.2018
comment
@Chris Stratton,это относится только к выполняемому им подпроцессу, а не к запрашивающему процессу Я никогда не говорил, что это не так. Вы наверняка знаете, как читать/записывать из подпроцесса программно. Задача нетривиальная и выходит за рамки вопроса... Понижение ответа мне кажется неразумным... - person Onik; 08.03.2018
comment
Хотя вы можете быть в курсе более подробной информации, ваш пост вводит в заблуждение и активно сбивает с толку людей. - person Chris Stratton; 08.03.2018
comment
Хотя этот ответ может предложить решение через adb, я думаю, что из формулировки ОП ясно, что автор ищет решение, позволяющее сделать это программно. Для ясности: если у вас нет root-доступа к Android Things, это решение не сработает, а рутирование устройства здесь действительно нереалистичный подход. - person Paul Lammertsma; 05.06.2018
comment
Пол Ламмертсма, ... еще один минус ... вы, кажется, друг Криса Стрэттона ... Я думаю, что из формулировки OP ясно, что автор ищет решение сделать это программно Ну, ОП вряд ли согласится с тобой. и рутирование устройства здесь действительно нереальный подход на чем он основан? Интересно посмотреть, как люди, имеющие некоторое представление о внутренностях Android, думают, что Android Things поддерживается как обычный стандартный телефон, в то время как множество /system/bin двоичных файлов Android Things являются исполняемыми всеми. - person Onik; 05.06.2018

Я думаю, что единственным решением является создание службы в init.rc, чтобы иметь возможность выполнять скрипт с правами root при загрузке. По-видимому, у вещей Android нет правильного решения. Что-то типа:

по свойству: dev.bootcomplete=1

start bootcomplete_handler

служба bootcomplete_handler /system/bin/sh /system/bin/bc_handler.sh

class late_start

user root

group root

disabled

oneshot

Но не знаю, сработает ли это

person D_Pablo    schedule 18.07.2018

Я сделал скрипт, который каждые 10 секунд, если обнаруживает USB-накопитель, монтирует его автоматически, единственная проблема - запустить его при загрузке, может быть, это может вам помочь, у меня есть мой пост здесь: Выполнить скрипт при загрузке Android Things

И сценарий:

while true; do

if [ "$( ls -l /dev/block/sd* | wc -l)" -ge 1 ];

then echo "partition available"

if [ "$( mount | grep  "usbAlv" -c)" -ge 1 ]; #if partition not mounted

then echo " Unit Mounted"

else

echo "not  mounted"


//if folder where we mount the partition doesnt exist

if [ !"$( ls -l /sdcard/usbAlv | wc -l)" -ge 1 ];

then mkdir /sdcard/usbAlv

fi

su root << EOSU

mount -t vfat -o rw /dev/block/sd* /sdcard/usbAlv

EOSU

fi

else

echo "not partition available"

fi

sleep 10;

done

Надеюсь, это поможет, я думаю, сейчас это единственный возможный способ сделать это программно

person In_va2    schedule 12.07.2018

Рабочие и отброшенные варианты

<сильный>1. Использовать ADB (работает)

Как ответчик от Onik в этом посте

<сильный>2. Использовать USB API (работает)

Поскольку Android API для USB поддерживает массовую передачу, вы можете кодировать команды, совместимые со SCSI.

Вы также можете попробовать существующие библиотеки, такие как libaums, опубликованные Phaestion в ответ на похожий вопрос

<сильный>3. Внедрить команды оболочки в init.rc в boot.img (НЕ работает)

Команды оболочки могут быть введены в файл init.rc внутри boot.img (не в файл init.rc, который вы можете найти в каталоге /root). Однако, учитывая характер загрузки компиляции AndroidThings AB, мне не удалось заставить ее работать.

<сильный>4. Добавить расширенные разрешения для приложений (НЕ работает)

Следующие разрешения кажутся многообещающими для выполнения корневых команд из приложения. Однако ошибка отказа в доступе продолжает блокировать выполнение корневой команды.

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.CALL_PRIVILEGED" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MANAGE_USB" tools:ignore="ProtectedPermissions" />

Я даже пытался скомпилировать дистрибутив AndroidThings с приложением с такими разрешениями, но консоль Android Things НЕ позволяет включать приложение в компиляцию.

<сильный>5. Белый список приложения (НЕ работает)

Существует белый список для привилегированных приложений. Однако этот белый список размещается в привилегированном каталоге и не может быть перезаписан даже из команды оболочки с пользователем root.

<сильный>6. Установите приложение в привилегированном месте (НЕ работает) Приложения, установленные в привилегированных каталогах, могут выполнять корневые команды. Однако AndroidThings НЕ позволяет устанавливать приложения в такие места (даже из оболочки с пользователем root).

person Ander Arizaga Martínez    schedule 22.01.2020
comment
Знаете ли вы, как использовать разрешение MOUNT_UNMOUNT_FILESYSTEMS? Я вижу много системных разрешений в разрешениях манифеста, и это круто. Но я не знаю, как их использовать, если кто-то уже не спросил! Знаете ли вы нормальную процедуру, чтобы узнать, что делать с разрешением? (PS: у меня приложение установлено на системный раздел, поэтому я могу иметь разрешение - просто понятия не имею, что с ним делать) Мы вызываем скрытые API (которые я тоже показываю - я не могу понять, как связываться с IStorageManager ...) или мы можем напрямую запускать предположительно корневые команды, не запрашивая root? - person DADi590; 22.10.2020