如何在 Android Things 上安装 USB 驱动器?
How to mount a USB drive on Android Things?
我正在尝试从 Android Things 应用程序的 USB 驱动器读取文件 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
但是,我的拇指驱动器不在列表中。所以我猜我需要以某种方式安装它。如何安装拇指驱动器并访问其中的文件?
仅 ADB 解决方案
好像现在 USB 驱动器还没有自动挂载。为了使您的代码正常工作,我必须手动安装它。
如您所见(来自 /proc/partitions
),在 /proc
分区中,USB 驱动器被检测为 sda
。
ADB挂载
创建一个挂载目录
mkdir /mnt/usb
安装设备
mount -t vfat -o rw /dev/block/sda1 /mnt/usb
现在您应该能够通过 ADB 和从应用程序中列出(和管理)USB 驱动器上的文件(/mnt/usb
也将被记录)。
我制作了一个脚本,如果检测到 USB 存储单元,它会每 10 秒自动安装它,唯一的问题是在启动时启动它,也许这可以帮助你,我的 post 在这里:
Execute Script on Boot 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
希望对您有所帮助,我想现在是唯一可行的编程方式
我认为唯一的解决方案是在 init.rc 中创建一个服务,以便能够在启动时以 root 权限执行脚本。
显然 Android 事情没有正确的解决方案。
类似于:
在 property: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
但不知道这样行不行
工作和废弃的选项
1.使用 ADB(工作)
作为 by Onik 在这个 post
2。使用 USB API(工作)
由于 USB 的 Android API 允许 bulkTransfer,您可以编写 SCSI 兼容命令。
您也可以尝试现有的库,例如 libaums, posted by Phaestion in response to this similar question
3。在 boot.img 处在 init.rc 处注入 shell 命令(不工作)
Shell 命令可以注入到 boot.img 内的 init.rc 文件(而不是可以在 /root 目录中找到的 init.rc 文件)。但是,考虑到 AndroidThings 编译的 A-B 引导性质,我一直无法让它工作。
4。添加高级应用权限(不工作)
以下权限似乎有望从应用程序执行根命令。但是,permission denied 错误 继续阻止 root 命令执行。
<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 分发,但 AndroidThings 控制台不允许将应用程序包含到编译中
5.将应用列入白名单(不工作)
特权应用程序有一个白名单。然而,这个白名单被放置在一个特权目录中,即使使用 root 用户 shell 命令也无法覆盖
6.在特权位置安装应用程序(不工作)
安装在特权目录中的应用程序可以执行 root 命令。但是,AndroidThings 不允许在这些位置安装应用程序(即使是 shell root 用户)
我正在尝试从 Android Things 应用程序的 USB 驱动器读取文件 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
但是,我的拇指驱动器不在列表中。所以我猜我需要以某种方式安装它。如何安装拇指驱动器并访问其中的文件?
仅 ADB 解决方案
好像现在 USB 驱动器还没有自动挂载。为了使您的代码正常工作,我必须手动安装它。
如您所见(来自 /proc/partitions
),在 /proc
分区中,USB 驱动器被检测为 sda
。
ADB挂载
创建一个挂载目录
mkdir /mnt/usb
安装设备
mount -t vfat -o rw /dev/block/sda1 /mnt/usb
现在您应该能够通过 ADB 和从应用程序中列出(和管理)USB 驱动器上的文件(/mnt/usb
也将被记录)。
我制作了一个脚本,如果检测到 USB 存储单元,它会每 10 秒自动安装它,唯一的问题是在启动时启动它,也许这可以帮助你,我的 post 在这里: Execute Script on Boot 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
希望对您有所帮助,我想现在是唯一可行的编程方式
我认为唯一的解决方案是在 init.rc 中创建一个服务,以便能够在启动时以 root 权限执行脚本。 显然 Android 事情没有正确的解决方案。 类似于:
在 property: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
但不知道这样行不行
工作和废弃的选项
1.使用 ADB(工作)
作为
2。使用 USB API(工作)
由于 USB 的 Android API 允许 bulkTransfer,您可以编写 SCSI 兼容命令。
您也可以尝试现有的库,例如 libaums, posted by Phaestion in response to this similar question
3。在 boot.img 处在 init.rc 处注入 shell 命令(不工作)
Shell 命令可以注入到 boot.img 内的 init.rc 文件(而不是可以在 /root 目录中找到的 init.rc 文件)。但是,考虑到 AndroidThings 编译的 A-B 引导性质,我一直无法让它工作。
4。添加高级应用权限(不工作)
以下权限似乎有望从应用程序执行根命令。但是,permission denied 错误 继续阻止 root 命令执行。
<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 分发,但 AndroidThings 控制台不允许将应用程序包含到编译中
5.将应用列入白名单(不工作)
特权应用程序有一个白名单。然而,这个白名单被放置在一个特权目录中,即使使用 root 用户 shell 命令也无法覆盖
6.在特权位置安装应用程序(不工作) 安装在特权目录中的应用程序可以执行 root 命令。但是,AndroidThings 不允许在这些位置安装应用程序(即使是 shell root 用户)