Android中通过USB连接来控制硬件设备

现在好多设备都有USB接口,在Android系统的手机或者开发板上可以实现通过USB来控制设备。一般手机上没有USB接口,需要使用OTG功能的转接线扩展出USB母口;一般Android开发板上带有USB口就可以直接使用了。

USB连接中需要知道对应USB设备的vendorId(设备厂商Id)和productId(设备产品Id),这两个id主要是用于连接和过滤设备。那么下面我们就先来看下拿到设备怎样找设备的vendorId和productId:

(1)先将设备通过USB口连接到电脑上;

(2)我的电脑->管理->设备管理器->找到链接的usb设备->右键属性->详细信息->硬件ID->其中的VID就是厂商id、PID是产品id。如下图所示:

这个ID是16进制的,需要转换成10进制的在  xml---device_filter.xml文件里配置。

在res目录下新建文件夹,名字是xml,然后再xml文件夹里新建device_filter.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!--设备过滤文件-->

    <!-- devices vendor-id= 0x1F3A product-id=0x1007-->
    <usb-device vendor-id="7994" product-id="4103"/>
</resources>

这里的每一个usb-device对应一个usb设备;如果应用需要对多个设备使用,这里可以添加多个usb-device对应的usb设备的vendor-id和product-id;如果应用可以对同一个厂商的所有设备使用,这里可以只写vendor-id(个人是这么理解的)。

前面的准备工作做好了就可以进行下面的开发了:

(1)在AndroidManifest.xml中申明USB权限:

<!-- 声明使用usb -->
    <uses-feature
        android:name="android.hardware.usb.host"
        android:required="true" />

(2)在AndroidManifest.xml中对应Activity中添加下面内容:

<!--获取USB操作的通知-->
    <intent-filter>
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
    </intent-filter>

<!-- android设备的信息过滤 -->
    <meta-data
        android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
        android:resource="@xml/usb_xml"/>

通过设备的vendorId(设备厂商Id)和productId(设备产品Id)找到设备

/**
     * 找到自定设备
     */
    public UsbDevice getUsbDevice(int vendorId, int productId) {
        //1)创建usbManager
        if (usbManager == null)
            usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);

        //2)获取到所有设备 选择出满足的设备
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            Log.e(TAG, "vendorID--" + device.getVendorId() + "ProductId--" + device.getProductId());
            if (device.getVendorId() == vendorId && device.getProductId() == productId) {
                return device; // 获取USBDevice
            }
        }
        statue = USBContent.usb_find_this_fail;
        return null;
    }

查找所有连接的USB设备,与上面的通过id查找设备  两者根据实际情况来选用。

    /**
     * 查找本机所有的USB设备
     */
    public List<UsbDevice> getUsbDevices() {
        //1)创建usbManager
        if (usbManager == null)
            usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);

        //2)获取到所有设备 选择出满足的设备
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        //创建返回数据
        List<UsbDevice> lists = new ArrayList<>();
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            Log.e(TAG, "vendorID--" + device.getVendorId() + "ProductId--" + device.getProductId());
            lists.add(device);
        }
        return lists;
    }

连接USB设备


    /**
     * 根据指定的vendorId和productId连接USB设备
     *
     * @param vendorId  产商id
     * @param productId 产品id
     */
    public int connection(int vendorId, int productId) {
        usbDevice = getUsbDevice(vendorId, productId);

        //3)查找设备接口
        if (usbDevice == null) {
            Log.e(TAG, "未找到目标设备,请确保供应商ID" + vendorId + "和产品ID" + productId + "是否配置正确");
            return statue;
        }
        UsbInterface usbInterface = null;
        for (int i = 0; i < usbDevice.getInterfaceCount(); i++) {
            //一个设备上面一般只有一个接口,有两个端点,分别接受和发送数据
            usbInterface = usbDevice.getInterface(i);
            Log.e("USBHelper","usbInterface.getEndpointCount()="+usbInterface.getEndpointCount());
            break;
        }

        //4)获取usb设备的通信通道endpoint
        for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
            UsbEndpoint ep = usbInterface.getEndpoint(i);
            switch (ep.getType()) {
                case UsbConstants.USB_ENDPOINT_XFER_BULK://USB端口传输
                    if (UsbConstants.USB_DIR_OUT == ep.getDirection()) {//输出
                        epBulkOut = ep;
                        Log.e(TAG, "获取发送数据的端点");
                    } else {
                        epBulkIn = ep;
                        Log.e(TAG, "获取接收数据的端点");
                    }
                    break;
                case UsbConstants.USB_ENDPOINT_XFER_CONTROL://控制端点
                    epControl = ep;
                    Log.e(TAG, "find the ControlEndPoint:" + "index:" + i + "," + epControl.getEndpointNumber());
                    break;
                case UsbConstants.USB_ENDPOINT_XFER_INT://中断端点
                    if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {//输出
                        epIntEndpointOut = ep;
                        Log.e(TAG, "find the InterruptEndpointOut:" + "index:" + i + "," + epIntEndpointOut.getEndpointNumber());
                    }
                    if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
                        epIntEndpointIn = ep;
                        Log.e(TAG, "find the InterruptEndpointIn:" + "index:" + i + "," + epIntEndpointIn.getEndpointNumber());
                    }
                    break;
                default:
                    break;
            }
        }

        //5)打开conn连接通道
        if (usbManager.hasPermission(usbDevice)) {
            //有权限,那么打开
            conn = usbManager.openDevice(usbDevice);
        } else {//没有权限
            usbManager.requestPermission(usbDevice, intent);// 先去获取权限
            if (usbManager.hasPermission(usbDevice)) { // 权限获取成功
                conn = usbManager.openDevice(usbDevice);
            } else {
                Log.e(TAG, "USB授权失败");
                statue = USBContent.usb_permission_fail;
            }
        }
        if (null == conn) {
            Log.e(TAG, "不能连接到设备");
            statue = USBContent.usb_open_fail;
            return statue;
        }

        //打开设备
        if (conn.claimInterface(usbInterface, true)) {
            if (conn != null)// 到此你的android设备已经连上设备
                Log.e(TAG, "open设备成功!");
            final String mySerial = conn.getSerial();
            Log.e(TAG, "设备serial number:" + mySerial);
            statue = USBContent.usb_ok;
        } else {
            Log.e(TAG, "无法打开连接通道。");
            statue = USBContent.usb_passway_fail;
            conn.close();
        }
        return statue;
    }

发送数据


    /**
     * 通过USB发送数据
     */
    public void sendData(byte[] buffer) {
        if (conn == null || epBulkOut == null) return;
        int res = conn.bulkTransfer(epBulkOut, buffer, buffer.length, 1000);
        Log.e(TAG, "res="+res);

        if (res  >= 0) {
            //0 或者正数表示成功
            Log.e(TAG, "发送成功");
            statue = USBContent.usb_permission_ok;
        } else {
            Log.e(TAG, "发送失败的");
            statue = USBContent.usb_permission_fail;
        }
    }

使用完关闭USB连接

    /**
     * 关闭USB连接
     */
    public void close() {
        if (conn != null) { //关闭USB设备
            conn.close();
            conn = null;
        }
        if (mContext != null && broadcastReceiver != null) {
            mContext.unregisterReceiver(broadcastReceiver);
        }
    }

到这里USB的连接、通过USB向硬件设备发送数据就完成了,在此做下记录,方便以后参考使用。大家如果看到了此文章,如果发现哪里有问题欢迎指正。(本人也是刚刚接触USB通信,对USB通信了解有限,上面这个是用到了亲自试验的记录一下)

感谢参考文章:https://blog.csdn.net/u013057253/article/details/82725585

还有一篇USB协议基本知识文章个人感觉写的也不错,对刚接触USB的会有帮助,附上个链接https://blog.csdn.net/u010142953/article/details/82627591

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Android系统提供的Camera API接口是可以用来控制外接USB摄像头的,该接口提供了与摄像头的使用相关的方法和类。通过调用该API的方法,可以实现对USB摄像头的控制,如拍照、录像、调整曝光、聚焦、缩放等操作。 在使用Camera API接口控制USB摄像头时,需要先检测设备和摄像头的连接情况,然后打开摄像头并获取相关的参数设置,比如摄像头分辨率、颜色格式等。接下来,可以开始获取预览数据、设置预览画面、进行拍照和录像等操作。 USB摄像头与Android系统的连接方式一般采用OTG线或HDMI接口或者使用无线方式连接。对于需要连接OTG线的摄像头,需要注意设备支持OTG功能和OTG线的连接方式。 总之,通过使用Camera API接口,可以实现对外接USB摄像头的控制,在许多应用场景下具有很大的可行性和实用性。 ### 回答2: Android系统提供了统一的Camera API接口,用于控制手机内置摄像头的各种功能。而通过第三方库的支持,Android也可以支持外接USB摄像头的控制。 与内置摄像头不同,USB摄像头需要一个USB OTG引擎来支持数据的传输。一些基于ARM的平板电脑和智能手机已经集成了USB OTG的功能,如果你的设备不支持,你需要一个USB OTG转接器来支持你的USB摄像头。 使用具体的摄像头库时,Android系统需要分别安装UVC(USB Video Class)和USB OTG驱动程序。一旦安装完成,开发人员就可以直接通过Camera API接口来控制USB摄像头。这些API包括打开摄像头、控制光圈、调整曝光时间、设置对焦模式等等。 需要注意的是,USB摄像头的性能和图像质量与设备或摄像头本身设定相关。而且,由于Android系统的碎片化,一些特定的设备可能需要适配特定的USB摄像头,请在事先查询用户的设备列表并做适配工作。 总之,通过使用Camera API接口,Android系统可以轻松地控制与扩展相机硬件设备。这使得开发人员可以更灵活地选择相机硬件,并创建更好的图像和视觉体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时代新人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值