关于Android与USB设备的连接,所能搜索到的资料特别的少,但恰恰接到了一个这样的需求,使用android平板通过USB与一个外接设备进行通讯,这个设备是一个压力感应器,在压力发生变化时可以测到相应的压力值,Android设备通过USB对设备进行供电并与该设备进行通讯,将测量到的数据读取下来并进行保存分析。这是一个典型的Android设备作为USBHost、外接设备作为USBDevice的Host Mode。关于Android所提供的USB连接模式,可以参考:http://developer.android.com/guide/topics/connectivity/usb/index.html,这里对两种连接模式都做了比较详细的介绍,不再赘述。下面主要针对我所遇到的问题做一些分析。

首先看Host mode所需要用的的类:

UsbManager:Allows you to enumerate and communicate with connected USB devices.字面含义就是允许你列举并与已连接的USB设备进行交互,其实就是一个USB管理器,可以通过它来获取已连接的USB Device列表。使用上很简单:UsbManager manager = (UsbManager) getSystemService(USB_SERVICE);就可以获取到一个实例。

USBDevice:Represents a connected USB device and contains methods to access its identifying information, interfaces, and endpoints.表示一个已连接的USB设备,包含获取它的识别信息、接口和端点的方法。获取一个USBDevice列表的方法:HashMap<String, UsbDevice> devices = um.getDeviceList();。

UsbInterface:Represents an interface of a USB device, which defines a set of functionality for the device. A device can have one or more interfaces on which to communicate on.表示一个为该设备定义了一个函数集的USB设备接口。一个设备可以拥有一个或多个用来交互的接口。获取一个设备的接口数量:int interfaceCount = device.getInterfaceCount();,如果使用index为0的interface则可以:UsbInterface ui = device.getInterface(0); 。

UsbEndpoint:Represents an interface endpoint, which is a communication channel for this interface. An interface can have one or more endpoints, and usually has input and output endpoints for two-way communication with the device. 表示一个接口端点,该端点作为这个接口的一个交互channel,一个接口可以拥有一个或多个端点,通常有输入和输出端点为一个设备提供两种交互方式。

UsbDeviceConnection:Represents a connection to the device, which transfers data on endpoints. This class allows you to send data back and forth sychronously or asynchronously.表示在通过端点与设备传输数据的一个连接,该类允许你同步或异步的发送信息出去或者回来。

在获取一个UsbEndpoint时,务必要执行conn.claimInterface(UsbInterface intf, boolean force)方法。在使用中

if(!um.hasPermission(device)){//判断是否拥有该设备的连接权限,如果没有则请求权限
    um.requestPermission(device, this.createPendingResult(0, null, 0));
}

if(manager.hasPermission(device)){//如果已经拥有该设备的连接权限
    conn = manager.openDevice(device);//打开一个UsbDeviceConnection
}

if(conn==null){
      Toast.makeText(this, "USB设备连接不可用!", Toast.LENGTH_SHORT).show();
      return false;
}
if(conn.claimInterface(ui, true)){//This must be done before sending or receiving data on any UsbEndpoints belonging to the interface.
      point = ui.getEndpoint(1);
      dataPoint = ui.getEndpoint(0);
      return true;
 }

如果配置正确的话,通过上面的几个类,应该可以成功的获得了一个可用的UsbEndpoint。

但需要注意的是,这时需要声明USB设备的信息,

<?xml version="1.0" encoding="utf-8"?>

<resources>

<usb-devicevendor-id="1234"product-id="5678"class="255"subclass="66"protocol="1"/>

</resources>

具体的这些id需要根据所连接的设备而有所不同,这个资源文件必须声明在res/xml/device_filter.xml中

完成这个声明以后,一般的,在USB设备接入时,系统如果检测到该设备,如果此时需要提示则应该

<manifest ...>

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

<uses-sdkandroid:minSdkVersion="12"/>

... <application>

<activity ...> ...

<intent-filter>

<actionandroid: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>

表示,在device_filter文件中的声明的设备连接到Android设备时,会触发连接的提示。

如果上面的连接正常,那么就可以与设备进行数据的传输了。

一般地,都会启动一个线程来完成这项工作。

request.initialize(conn, dataPoint);//初始化请求
ByteBuffer bb =ByteBuffer.allocate(2);//数据接收的ByteBuffer,具体大小要根据不同的设备而有所不同
while(canStop){
    request.queue(bb, 2);
    byte[] dst = new byte[2];
    int accessRes = conn.bulkTransfer(point, access, 2, 1000);//发送USB外设所能执行的命令
    if(accessRes<0){
        return;
    }
    if(request == conn.requestWait()){//请求完成,如果发生错误则方法返回null
        dst = bb.array();//返回的数据

}

}

UsbRequest:Represents an asynchronous request to communicate with a device through aUsbDeviceConnection.表示通过一个UsbDeviceConnection实例与设备进行交互的一个异步请求。

在这个数据传输的过程中,需要发送命令和接收数据,发送命令的方法有两个:

controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int length, int timeout)

Performs a control transaction on endpoint zero for this device.
参数requestType,该事务的请求类型,参数request,该事务的请求ID,参数value,该事务的值,参数index,该事务的索引,参数buffer,该事务的数据buffer,如果没有数据需要被发送或接收,可以为null,参数length,发送或接收数据的长度,参数timeout,超时时间,单位毫秒
另外一个是,
bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)

Performs a bulk transaction on the given endpoint.
参数endpoint,需要通过哪个端点来发送数据,参数buffer,要发送或接收的数据buffer,参数length,要发送或接收的数据长度,参数timeout,超时时间,单位毫秒
如果返回值为负值,则说明失败,否则返回发送成功数据的长度。
在发送完毕后,应当使用UsbDeviceConnection的requestWait()方法来等待响应获取返回的数据。
至此,整个连接设备与数据交互的过程就可以算完成了,具体到发送什么样的命令,根据所连接设备的不同自然也是不同的,整个流程大致就如上面所说。Google也提供了一个Demo,如果没有下载的话可以在 这里下载

Android设备与USB设备的连接通讯相关推荐

  1. Android系统插入USB设备自动授权不弹出对话框

    Android系统插入USB设备时,系统会弹出询问权限的对话框,现在需要不弹对话框而直接授权. 修改/frameworks/base/packages/SystemUI/src/com/android ...

  2. linux关于usb的使用,linux之常见的使用USB设备,linuxusb设备这些USB设备包括U

    linux之常见的使用USB设备,linuxusb设备这些USB设备包括U 软驱这个曾经的鸡肋终于彻底从电脑上消失了,取而代之的是容量更大,携带更方便,传输速度更快的USB设备.这些USB设备包括U盘 ...

  3. Android监控外接USB设备和获取USB等设备的详细信息

    1.通过如下Action监控USB设备的插入或拔出 UsbManager.ACTION_USB_ACCESSORY_ATTACHED;UsbManager.ACTION_USB_ACCESSORY_D ...

  4. Android 监听USB设备插拔事件

    通过注册广播的方式监听USB设备 . 广播Action UsbManager.ACTION_USB_DEVICE_ATTACHED Usb设备插入或者挂载事件通知 UsbManager.ACTION_ ...

  5. 【远程访问与设备重定向】上海道宁为您助您远程共享USB设备与USB设备重定向到远程会话

    USB over Network用于 通过LAN或Internet 与远程USB设备进行通信 远程USB设备可供多个用户共享 当您连接远程共享USB设备时 它们会被识别为 直接连接到本地计算机 USB ...

  6. usb打印机命令_Hyper-V与你的虚拟机共享设备、USB设备

    仅适用于 Windows 虚拟机. 增强会话模式可通过 RDP(远程桌面协议)将 Hyper-V 与虚拟机连接起来. 这不仅会改善你的整体虚拟机查看体验,而且使用 RDP 连接还可以使虚拟机与你的计算 ...

  7. QT5.15使用VISA接口连接GPIB设备和USB设备

    本文是之前再外网找到的解决方法,本着分享目的共享出来. 1. 首先安装NI-VISA环境包:点击下载 如果使用GPIB还需要安装GPIB的环境包:点击下载(这个忘记了,似乎不安装也行) 2. 安装完成 ...

  8. linux 设备型号,根据USB设备硬件信息获取Android设备型号

    前些日子,自己接手专门为Android设备开发的数据恢复软件,第一次作为项目经理带队进行项目开发. 其中为了解决设备和型号的对应关系,用于区分当前接入系统的设备是USB设备,并且是Android设备而 ...

  9. 一文入门USB设备的驱动编写方法

    摘要:本文介绍了USB设备驱动相关的基本知识结构,和编写驱动的基本步骤和流程.最后通过编写一个USB鼠标的驱动实力,讲述了简单字符型USB输入设备驱动的具体编写步骤,并给予了测试方法.文末附有完整程序 ...

最新文章

  1. 第二阶段个人总结06
  2. android检查新版本,详解Android Studio无法检测新版本问题解决
  3. Linux文件系统与日志分析(inode、inode节点耗尽故障处理、文件备份和恢复、日志文件管理)
  4. 今年大学毕业照画风太清奇.....我忍不住笑出了声!
  5. Java 9中的进程处理
  6. c# 无法将类型隐式转换_C#中的隐式类型数组
  7. oracle 怎么备份sqlserver数据库,Oracle和sqlserver数据库的备份与恢复
  8. 使用mybatis插入数据(insert)时返回主键的问题
  9. 一个优秀数据分析师的准则
  10. 深度学习2.0-32.经典卷积网络VGG,GoogleNet,Inception-1
  11. 熬了一个通宵,终于把Reids的7千万个Key删完了,今天脑子都嗡嗡响!
  12. 深入理解for循环(执行顺序)
  13. 汽车CAN总线思维导图
  14. 2021-09-10ESSM, CVR预估到底要预估什么
  15. GS运维常用工具及文档
  16. 钢铁侠机器人公仔_自己再演一遍复联!优必选钢铁侠 MK50 机器人评测
  17. java espresso_java – 带有片段的Android Espresso功能测试
  18. python深度学习tensorflow和fme结合,实现档案扫描件数据自动分类
  19. 图片复制word java_java poi实现word导出(包括word模板的使用、复制表格、复制行、插入图片的使用)...
  20. 基于python中jieba包的中文分词中详细使用(一)

热门文章

  1. Hello Qt(一)——QT简介
  2. 新版标准日本语高级_第24课
  3. 重磅!《2022中国开源发展蓝皮书》正式发布
  4. 电脑windows安装Mysql数据库
  5. linux 删除文件夹admin 报错 Linux cannot remove is a directory
  6. (转载)Nim游戏博弈(收集完全版)
  7. 【愚公系列】2022年09月 微信小程序-WebGL画渐变色正方形
  8. 【服务器搭建个人网站】教程五:手把手教你怎样进行公安备案 快来学~
  9. python-Non-UTF-8 code starting with ‘\xbd‘ in file C:/Users/Adminis.....出错
  10. 老马失足 波音KC-46加油机为何如此拖拉?