• 安卓USB模块分析(二)- API使用


    Android USB 支持两种模式:1. 主机模式;2. 配件模式;这里我们主要梳理HOST模式的使用;

    USB 模块的使用可参考官方文档:

    USB 主机和配件概览  |  Android 开发者  |  Android Developers (google.cn)

    使用流程总结

    1. 发现连接的 USB 设备,具体方法是使用 Intent 过滤器在用户连接 USB 设备时接收通知,或者枚举已连接的 USB 设备。
    2. 请求用户授予连接到 USB 设备的权限(如果尚未获得权限)。
    3. 通过在适当的接口端点读取和写入数据来与 USB 设备通信。
    4. 完成通信或设备断开后释放资源。

    配置清单文件

    1. 使用 来声明需要使用 android.hardware.usb.host
    2. 通过 intent-filter 来声明接收USB设备连接的通知;
      1. 通过 action 声明通知类型
      2. 通过 meta-data 声明感兴趣的设备(过滤);
    <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>  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    device-filter 文件:

        
        <resources>
            <usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" />
        resources>
    
    • 1
    • 2
    • 3
    • 4

    如果您想过滤某个特定设备,请使用供应商 ID 和产品 ID;如果您想过滤一组 USB 设备(例如大容量存储设备或数码相机),请使用类、子类和协议。您可以指定所有这些属性,也可以不指定任何属性。如果不指定任何属性,则会与每个 USB 设备进行匹配

    获取设备

    1. 获取触发设备
    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
    
    • 1
    1. 枚举设备
      通过 getDeviceList 方法来枚举设备:
        UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
        ...
        HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
        UsbDevice device = deviceList.get("deviceName");
    
    • 1
    • 2
    • 3
    • 4

    申请通信权限

    1. 如果应用使用 Intent 过滤器来发现已连接的 USB 设备,则它会在用户允许应用处理 Intent 时自动获得权限。否则,必须在应用中明确请求权限,然后才能连接到设备。
    2. 手动申请权限
    3. 创建广播接收器
        private static final String ACTION_USB_PERMISSION =
            "com.android.example.USB_PERMISSION";
        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 = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                        if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                            if(device != null){
                              //call method to set up device communication
                           }
                        }
                        else {
                            Log.d(TAG, "permission denied for device " + device);
                        }
                    }
                }
            }
        };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 注册广播接收器:
    UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        private static final String ACTION_USB_PERMISSION =
            "com.android.example.USB_PERMISSION";
        ...
        permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(usbReceiver, filter);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. requestPermission
        UsbDevice device;
        ...
        usbManager.requestPermission(device, permissionIntent);
    
    • 1
    • 2
    • 3

    当用户在该对话框中作出回复时,广播接收器会收到包含 EXTRA_PERMISSION_GRANTED extra 的 Intent,即表示回答的布尔值。在连接到设备之前,需要检查此 extra 的值是否为 true。

    设备通信

    与 USB 设备的通信可以是同步的,也可以是异步的。在两种情况下,都应该创建一个新线程来执行所有数据传输,这样就不会锁定UI线程。要正确设置与设备的通信,需要获取要与之通信的设备的相应 UsbInterface 和 UsbEndpoint,并使用 UsbDeviceConnection 在此端点发送请求。通常,您的代码应该执行以下操作:

    • 检查 UsbDevice 对象的属性(例如产品 ID、供应商 ID 或设备类别),判断您是否要与设备通信。
    • 在您确定要与设备通信时,找到您要用于通信的适当 UsbInterface 以及该接口的适当 UsbEndpoint。接口可以具有一个或多个端点,并且通常具有用于双向通信的输入和输出端点。
    • 找到正确的端点后,在该端点上打开 UsbDeviceConnection
    • 使用 bulkTransfer() 或 controlTransfer() 方法提供要在端点上传输的数据。您应该在另一个线程中执行此步骤,以防止主界面线程被锁定。如需详细了解如何在 Android 中使用线程,请参阅进程和线程

    同步数据传输

      private Byte[] bytes;
      private static int TIMEOUT = 0;
      private boolean forceClaim = true;
    
      UsbInterface intf = device.getInterface(0);
      UsbEndpoint endpoint = intf.getEndpoint(0);
      UsbDeviceConnection connection = usbManager.openDevice(device);
      connection.claimInterface(intf, forceClaim);
      //do in another thread
      connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    异步数据传输

    使用 UsbRequest 类以 initialize 和 queue 异步请求,然后使用 requestWait() 等待结果。

    如需了解详情,请参阅 AdbTest 示例(展示了如何执行异步批量传输)和 MissileLauncher 示例(展示了如何异步监听中断端点)。

    终止通信

    • 监听断开连接事件,创建如下广播接收器:
     BroadcastReceiver usbReceiver = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
    
              if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                    UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (device != null) {
                        // call your method that cleans up and closes communication with the device
                    }
                }
            }
        };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 当完成与设备的通信或者设备断开连接后,调用 releaseInterface() 和 close() 来关闭 UsbInterface 和 UsbDeviceConnection
  • 相关阅读:
    【数据结构复习之路】线性表(严蔚敏版)万字详解&主打基础
    全排列——dfs(剪枝/回溯)
    网络教学管理系统
    迅为龙芯开发板系统编译安装pmoncfg
    AI 游戏工具收集
    抖音店铺提供优质服务|成都瀚网科技
    ios 运行ipa包 日志查看方式
    【javaEE】网络原理(传输层Part2)
    Git 基本原理和常用操作
    支持向量机(SVM)案例分析
  • 原文地址:https://blog.csdn.net/mospuito/article/details/126168101