Android 实现 USB 通讯

在现代移动设备和 periferal 设备的交互中,USB 通讯是非常重要的一个部分。Android 系统为 USB 通讯提供了一整套 API,允许开发者与 USB 设备进行交互。本文将深入探讨如何在 Android 中实现 USB 通讯,同时提供详细的代码示例。

1. USB 通讯基础

USB(Universal Serial Bus)是一种通用的数据传输协议,广泛应用于各种电子设备之间的数据交换。在 Android 中,USB 通讯通常用于连接外部硬件如打印机、扫描仪、传感器等。通过 Android 提供的 USB Host API,开发者能够查询连接的 USB 设备、获取设备信息以及实现数据传输。

2. 开发准备

在开始之前,您需要确保以下几个条件:

  • Android Studio 及相关的开发环境已安装
  • 一台支持 USB Host 的 Android 设备
  • 适用于您的设备的 USB 外设

您还需要在 AndroidManifest.xml 中声明 USB 权限和过滤器:

<manifest xmlns:android="
    package="com.example.usbcommunication">

    <uses-feature android:name="android.hardware.usb.host" />

    <uses-permission android:name="android.permission.USB_PERMISSION" />

    <application>
        <activity>
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            </intent-filter>

            <meta-data
                android:name="android.hardware.usb.device"
                android:resource="@xml/device_filter" />
        </activity>
    </application>
</manifest>

同时需要创建一个 device_filter.xml 文件来指定支持的 USB 设备:

<resources>
    <usb-device vendor-id="1234" product-id="5678" />
</resources>

3. 检测 USB 设备

我们可以通过 UsbManager 来获取连接的 USB 设备并做相应的处理。以下是检测设备的代码示例:

UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();

for (UsbDevice device : deviceList.values()) {
    // 获取设备信息
    Log.d("USB Device", "Device Name: " + device.getDeviceName());
    Log.d("USB Device", "Vendor ID: " + device.getVendorId());
    Log.d("USB Device", "Product ID: " + device.getProductId());
    
    // 处理设备
    // ...
}

4. 请求权限

在访问 USB 设备之前,您需要请求用户权限。您可以使用如下代码请求权限:

UsbDevice device = /* 获取到的 UsbDevice */;
PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, permissionIntent);

还需要创建一个广播接收器来处理用户的授权响应:

private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_USB_PERMISSION.equals(action)) {
            synchronized (this) {
                UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if (device != null) {
                        // 拥有权限
                        openDevice(device);
                    }
                } else {
                    Log.d("USB", "Permission denied for device " + device);
                }
            }
        }
    }
};

5. 打开 USB 设备

权限获得后,您可以开始与设备进行通讯。打开 USB 设备的代码示例如下:

private void openDevice(UsbDevice device) {
    UsbDeviceConnection connection = usbManager.openDevice(device);
    if (connection != null) {
        UsbInterface usbInterface = device.getInterface(0);
        connection.claimInterface(usbInterface, true);
        
        // 进行读写
        // ...
    } else {
        Log.d("USB", "Failed to open device");
    }
}

6. 数据读写

与 USB 设备成功连接后,您可以读取或写入数据。以使用 UsbEndpoint 进行数据通讯为例:

UsbEndpoint endpointIn = usbInterface.getEndpoint(0); // 输入端
UsbEndpoint endpointOut = usbInterface.getEndpoint(1); // 输出端

// 读取数据
byte[] buffer = new byte[64];
int bytesRead = connection.bulkTransfer(endpointIn, buffer, buffer.length, 1000);

// 发送数据
byte[] data = "Hello USB".getBytes();
int bytesWritten = connection.bulkTransfer(endpointOut, data, data.length, 1000);

7. Gantt 图示例

为了更清晰地展示 USB 通讯开发的流程,我们使用 Gantt 图进行说明。流程包括设备检测、权限请求、设备打开和数据交换等环节。

gantt
    title USB Communications Development Process
    dateFormat  YYYY-MM-DD
    section Preparation
    Setup Android Studio          :a1, 2023-09-01, 3d
    Declare Permissions            :a2, after a1, 1d
    Setup Filter                  :a3, after a2, 1d

    section Device Connection
    Detect USB Devices            :b1, 2023-09-05, 2d
    Request USB Permission         :b2, after b1, 1d
    Device Open                   :b3, after b2, 1d

    section Data Exchange
    Write Data                    :c1, 2023-09-09, 2d
    Read Data                     :c2, after c1, 2d

8. 结论

通过 Android 的 USB Host API,我们可以相对简单地实现 USB 设备的通讯。本文提供的代码示例和步骤,可以帮助开发者在项目中快速集成 USB 交互功能。从权限处理到数据传输,每一步都是与外部硬件成功交互的关键。

无论是开发终端设备、外围设备,还是智能家居的各种应用,这些知识都将对您参透 USB 通讯的机制、架构大有裨益。希望这篇文章能够为您提供一些有价值的参考,助力您的开发之路。如果有任何疑问或需深入探讨的内容,欢迎随时寻求帮助。