以下步骤可用于解决您提到的问题。
将设备安装为 USB 大容量存储设备的过程在设备之间和特定于制造商的情况下不一致。当您通过 USB 电缆将设备连接到桌面时,某些设备(如 Nexus S)会提供“打开 USB 存储”。Galaxy S3 等其他设备现在需要一个应用程序才能将该设备作为大容量存储启动。无论哪种方式,Android 设备通常都提供这样的功能,您必须创建一个与您的设备制造商规范相匹配的文件。
在使用 USB 主机 API 之前,您需要添加到应用程序的清单文件中:
- 由于并非所有 Android 驱动的设备都保证支持 USB 主机 API,因此请包含一个声明您的应用程序使用 android.hardware.usb.host 功能的元素。
- 如果您希望您的应用程序收到连接的 USB 设备的通知,请在您的主活动中为 android.hardware.usb.action.USB_DEVICE_ATTACHED Intent 指定一个元素对。
将 USB_DEVICE_ATTACHED 添加到清单文件中:
<manifest ...>
<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk android:minSdkVersion="12" />
...
<application>
<activity ...>
...
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
</application>
</manifest>
为了帮助您的 APP 发现特定的 USB 设备,您可以使用意图过滤器:
<activity ...>
...
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
您还必须指定您的设备和供应商 ID:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1234" product-id="5678" />
</resources>
这应该足以处理您的USB 主机连接。现在调用 USB:
int LIBUSB_CALL libusb_open2(libusb_device *dev, libusb_device_handle **handle, int fd);
使用描述符打开与USB 设备的连接- 例如:
UsbManager myUsbManager = (UsbManager)
getSystemService(Context.USB_SERVICE);
UsbAccessory myUsbAccessory = (myUsbManager.getAccessoryList())[0];
ParcelFileDescriptor pfd = myUsbManager.openAccessory(myUsbAccessory);
FileDescriptor fileDescriptor = pfd.getFileDescriptor();
FileInputStream myFileInputStream = new FileInputStream(fileDescriptor);
FileOutputStream myFileOutputStream = new FileOutputStream(fileDescriptor);
如果您仍然遇到 SELinux 级别的问题,您可以在此处进行一些编辑,以使您的程序顺利运行:
// default.prop
ro.secure=1 -----------------> ro.secure=0
ro.adb.secure=1 -----------------> ro.adb.secure=0
//init.rc
setsebool debugfs 1 --------> setsebool debugfs 0
setenforce 0
setprop selinux.reload_policy 1 -------> setprop selinux.reload_policy 0
// init.target.rc
setprop selinux.reload_policy 1 -----> setprop selinux.reload_policy 0
由于SELinux默认设置为强制执行最高安全性,并且您希望授予客户端通过 USB 访问您的 Android 设备的权限。

根据您的 Android 品牌和型号,尝试拔下连接设备和桌面的 USB 电缆,然后重新插入。系统应该会提示您“打开 USB”存储。如果是这种情况,请继续尝试在 Android 上浏览设置 → 更多...,然后寻找 USB 大容量存储选项。

(来源:pocketables.com)
或者查找设备制造商推荐的 USB 大容量存储过程。当您打开 USB 存储设备时,设备会让您知道某些应用程序将停止,继续操作即可。现在转到您的台式计算机并浏览到您的 USB 大容量存储介质,如果您没有重命名它,通常称为 NO NAME。单击您的大容量存储设备,然后在 foot 文件夹中找到一个名为 data.tsv 的文件。

您还可以通过在您喜欢的文本编辑器中打开 data.tsv 来检查它。你会发现有两列被标签整齐地分开;在每一行中,您都会找到一对整数值。这对于我们的项目来说已经足够了。更复杂的数据项目通常要求每一行都有一个唯一标识符,一个表中的一行指向另一个表中的特定记录。

根据您的开发环境,您还必须相应地调整您的设置。如果您在 Windows 上进行开发,请按照可用的 USB 驱动程序安装说明进行操作。如果您在 Linux 上进行开发,请按照说明设置您的设备以进行开发。

此外,还值得一提的是,之前发布的很多Android驱动的设备只能充当USB设备,无法发起与外部USB设备的连接。Android Open Accessory (AOA) 支持克服了这一限制,并允许您通过允许配件启动连接来构建可以与各种 Android 设备进行交互的配件。在项目中可以找到 Android Open Accessory 的一个常见使用示例:使用USB 主机模式录制和播放音频- 这当然需要 USB 模式启动并运行。

让 Android 通过 USB 与Arduino微控制器进行通信也是一种最近非常成功的实现方式,因为它允许您通过多设备解决方案方法来扩展集成附加功能的 Android 功能。允许设备与您的 Android USB 通信的典型 Arduino Sketch 如下所示:
// the USB Host libraries
#include <Max3421e.h>
#include <Usb.h>
// the AOA library
#include <AndroidAccessory.h>
void setup();
void loop();
void setup()
{ // start serial debugging
Serial.begin(115200);
Serial.print("\r\nADK has run setup().");
Serial.println("Ready to start USB communication...");
}
void loop()
{ // example - read the voltage from a sensor
uint16_t val;
val = analogRead(TEMP_SENSOR); // or any sort of input
Serial.println(val,HEX);
Serial.write(val);
// Delay for 100 milliseconds.
delay(100);
}
所有 Arduino 项目都必须声明一个 setup() 和一个 loop() 方法,否则您的 Android 将无法正常通信。
还要记住使用 AOA 所需的最低要求列表:
- 兼容 AOA 的 Android 设备。要在尝试此示例之前测试兼容性,请参阅“支持的 Android 设备”部分以获取指向 Google Play 上提供的 Microchip AOA 演示应用程序的链接。
- 兼容的微控制器板。如果您不确定,Arduino Mega ADK 将是一个简单的选择。

使用 USB 的 Android 设备的可能性是惊人的,对能够充分利用这些功能的创新 APP 的需求将显着增长。