如何在 Android Things 上安装 USB 驱动器?

Posted

技术标签:

【中文标题】如何在 Android Things 上安装 USB 驱动器?【英文标题】:How to mount a USB drive on Android Things? 【发布时间】:2017-07-16 20:39:30 【问题描述】:

我正在尝试为 Raspberry Pi 上的 android Things 应用从 USB 驱动器读取文件。我可以像这样扫描已安装设备的列表:

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();
    

显示以下输出:

我:已安装:/ 我:挂载:/dev 我:挂载:/dev 我:挂载:/dev/pts 我:挂载:/dev/memcg 我:挂载:/dev/cpuctl 我:挂载:/proc 我:挂载:/sys 我:挂载:/sys/fs/selinux 我:挂载:/sys/fs/pstore 我:安装:/acct 我:安装:/mnt I:挂载:/mnt/runtime/default/emulated 我:挂载:/mnt/runtime/read/emulated I:挂载:/mnt/runtime/write/emulated 我:挂载:/config 我:安装:/数据 我:安装:/oem 我:安装:/gapps 我:安装:/存储 I:已安装:/storage/emulated 我:已安装:/storage/self 一:读取/proc/partitions的内容 I:主要次要#blocks 名称 我:1 0 8192 内存0 我:1 1 8192 ram1 我:1 2 8192 ram2 我:1 3 8192 ram3 我:1 4 8192 ram4 我:1 5 8192 ram5 我:1 6 8192 ram6 我:1 7 8192 ram7 我:1 8 8192 ram8 我:1 9 8192 ram9 我:1 10 8192 ram10 我:1 11 8192 ram11 我:1 12 8192 ram12 我:1 13 8192 ram13 我:1 14 8192 ram14 我:1 15 8192 ram15 我:179 0 7761920 mmcblk0 我:179 1 65536 mmcblk0p1 我:179 2 1024 mmcblk0p2 我:179 3 1024 mmcblk0p3 我:179 4 32768 mmcblk0p4 我:179 5 32768 mmcblk0p5 我:179 6 524288 mmcblk0p6 我:179 7 524288 mmcblk0p7 我:179 8 64 mmcblk0p8 我:179 9 64 mmcblk0p9 我:179 10 1024 mmcblk0p10 我:179 11 32768 mmcblk0p11 我:179 12 32768 mmcblk0p12 我:179 13 262144 mmcblk0p13 我:179 14 262144 mmcblk0p14 我:179 15 2683736 mmcblk0p15 我:8 0 7847935 sda 我:8 1 7845888 sda1

但是,我的拇指驱动器不在列表中。所以我猜我需要以某种方式安装它。如何安装 U 盘并访问其中的文件?

【问题讨论】:

【参考方案1】:

仅亚行解决方案

目前看来,USB 驱动器并未自动挂载。为了使您的代码正常工作,我必须手动安装它。

正如您在/proc 分区中看到的(来自/proc/partitions),USB 驱动器被检测为sda

ADB 安装

创建要挂载到的目录

mkdir /mnt/usb

安装设备

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

现在您应该能够通过 ADB 和在应用程序中列出(和管理)USB 驱动器上的文件(/mnt/usb 也会被记录)。

【讨论】:

对,直到建议您可以从应用程序中执行此操作,这在期望和方法上都存在严重错误 - 即使“su”可以“获得”,也无法“获得”(这里不太可能! ) 它只适用于它运行的子进程,而不是请求进程。 @Chris Stratton,“su 无法获得,即使它有效(这里不太可能!)” 为什么?你有listed system/xbin 对于Android Things 的任何版本吗? su 在第一个开发者预览版中发布... @Chris Stratton,“它只适用于它运行的子进程,而不是请求进程” 我从来没有告诉过它是另一种方式。您肯定知道如何以编程方式从子进程读取/写入。这项任务并非微不足道,超出了问题的范围......对我来说,拒绝回答似乎是不合理的...... 虽然您可能知道更多细节,但您的帖子具有误导性,并且会严重混淆人们。 虽然这个答案可能会通过 adb 提供解决方案,但我认为从 OP 的表述中可以清楚地看出作者正在寻找一种以编程方式执行此操作的解决方案。需要明确的是:除非您在 Android Things 上具有 root 访问权限,否则此解决方案将无法正常工作,并且在此对设备进行 root 确实是一种不切实际的方法。【参考方案2】:

我认为唯一的解决方案是在 init.rc 中创建一个服务,以便能够在启动时以 root 权限执行脚本。 显然Android的东西没有正确的解决方案。 比如:

关于属性:dev.bootcomplete=1

start bootcomplete_handler

service bootcomplete_handler /system/bin/sh /system/bin/bc_handler.sh

class late_start

user root

group root

disabled

oneshot

但不知道这是否可行

【讨论】:

【参考方案3】:

我制作了一个脚本,如果检测到 USB 存储单元每 10 秒自动安装一次,唯一的问题是在启动时启动它,也许这对你有帮助,我在这里有我的帖子: 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

希望它有所帮助,我想现在是唯一可能以编程方式完成它的方法

【讨论】:

【参考方案4】:

有效和废弃的选项

1.使用亚行(工作)

作为answererOnik 在这篇文章中

2。使用 USB API(工作)

由于适用于 USB 的 Android API 允许 bulkTransfer,因此您可以编写 SCSI 兼容命令。

您还可以尝试现有的库,例如Phaestion 发布的libaums 以响应this similar question

3.在 boot.img 的 init.rc 中注入 shell 命令(不工作)

Shell 命令可以注入到 boot.img 中的 init.rc 文件(而不是您可以在 /root 目录中找到的 init.rc 文件)。但是,鉴于 AndroidThings 编译的 A-B 启动性质,我无法使其工作。

4.添加高级应用权限(不起作用)

以下权限似乎有望从应用程序执行 root 命令。但是,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 发行版,但 Android Things 控制台不允许将应用程序包含到编译中

5.将应用列入白名单(不工作)

有特权应用程序的白名单。然而,这个白名单被放置在一个特权目录中,即使是 root 用户的 shell 命令也无法覆盖

6.在特权位置安装应用程序(不工作) 安装在特权目录中的应用程序可以执行 root 命令。但是,AndroidThings 不允许在这些位置安装应用程序(即使是从 shell 使用 root 用户)

【讨论】:

您知道如何使用 MOUNT_UNMOUNT_FILESYSTEMS 权限吗?我在 Manifest 权限上看到了许多系统权限,这很酷。但是除非有人问过,否则我不知道如何使用任何东西!您知道了解如何处理许可的正常程序吗? (PS:我在系统分区上安装了应用程序,所以我可以获得权限 - 只是不知道如何处理它)我们调用隐藏的 API(我也展示过 - 我不明白如何弄乱 IStorageManager ...) 或者我们可以直接运行所谓的 root 命令而不请求 root?

以上是关于如何在 Android Things 上安装 USB 驱动器?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Raspberry Pi 3模块上启用I2C(与Android Things一起使用作为操作系统)

在Android Things上扫描Wifi网络会返回空列表

MediaPlayer无法在Android Things Raspberry Pi 3上运行

从Android Things设备上的应用程序中选择WiFi网络(Raspberry Pi 3)

Android Things:在 Raspberry PI 3 上通过 USB UART 接收数据时出现 NullPointerException

Android Things在 #io17