android 在使用Usb设备遇到的问题总结

下面的场景都是安卓设备作为主机模式来说明的

Android系统提供在设备为主机模式下的Usb管理工具UsbManager,相关的类说明:
UsbDevice:连接到Android主机的Usb设备,一个或多个
UsbInterface: UsbDevice中提供的功能接口,一个或多个
UsbEndpoint: UsbInterface中提供的数据传输通道,一个或多个

  • 通过Usb连接的两个设备,怎么区分主机(host )和从(accessory/配件)?
    在这里插入图片描述

上图中B连接的是主机,A连接的是外设。手持Android设备没有B的插口,可以使用OTG转接线

  • 怎么获取和筛选连接到安卓设备(主机)上的UsbDevice?
    UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
    ...
    HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
    UsbDevice device = deviceList.get("deviceName");

通过UsbDevice 的mClass类别来区分

//UsbDevice.java
    public int getDeviceClass() {
        return mClass;
    }

不同的类别

//UsbConstants.USB_CLASS_前缀的常量
     /**
     * USB class for printers. 打印设备
     */
    public static final int USB_CLASS_PRINTER = 7;

UsbDevice 的一些名称和id

字段说明
mName设备名称
mManufacturerName制造商名称
mProductName产品名称
mVendorId供应商Id
mProductId产品Id

检查 UsbDevice 对象的属性(例如产品 ID、供应商 ID 或设备类别),判断您是否要与设备通信.这个没有固定的,看需求,比如支持哪些mVendorId或者mProductId

  • 怎么获取和筛选UsbDevice上提供的UsbInterface?
    Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
    while(deviceIterator.hasNext()){
        UsbDevice device = deviceIterator.next();
        //your code
    }

通过UsbInterface 的mClass类别来区分,同上

  • 怎么获取和筛选UsbInterface上提供的UsbEndpoint?

通过getType区分,选择你的数据交互方式,同步异步,批量等

   /**
     * Returns the endpoint's type.
     * Possible results are:
     * <ul>
     * <li>{@link UsbConstants#USB_ENDPOINT_XFER_CONTROL} (endpoint zero)
     * <li>{@link UsbConstants#USB_ENDPOINT_XFER_ISOC} (isochronous endpoint)
     * <li>{@link UsbConstants#USB_ENDPOINT_XFER_BULK} (bulk endpoint)
     * <li>{@link UsbConstants#USB_ENDPOINT_XFER_INT} (interrupt endpoint)
     * </ul>
     *
     * @return the endpoint's type
     */
    public int getType() {
        return mAttributes & UsbConstants.USB_ENDPOINT_XFERTYPE_MASK;
    }
  • 怎么获取UsbDevice权限?什么时候需要重新获取?

在尝试与设备通信之前,您必须先检查是否具有访问设备的权限。否则,如果用户拒绝授予访问设备的权限,您会收到运行时错误消息。要明确获取权限,请先创建广播接收器。此接收器监听在您调用 requestPermission() 时接收广播的 Intent。调用 requestPermission() 会向用户显示一个对话框,请求连接到设备的权限。以下示例代码展示了如何请求设备的权限:usb权限的时效:usb权限获取后,应用进程不被杀死是一直有的,下次重新打开app需要重新获取;

 //定义广播接受权限通知
 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);
                    }
                }
            }
        }
    };
     //注册广播接受权限通知
    permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    registerReceiver(usbReceiver, filter);
    //要显示对话框以向用户请求连接到设备的权限
    UsbDevice device;
    ...
    usbManager.requestPermission(device, permissionIntent);
  • 怎么和UsbDevice通信,终止通信?

以下代码段是执行同步数据传输的一种简单方式

    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);
    connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT); //do in another thread
    

终止与设备的通信

connection.releaseInterface(usbInterface);
connection.close();

谷歌USB开发者文档

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值