1 引言

随着安卓手机的市场份额逐步增加,安卓系统的功能也日益强大。使用手机与各类设备通信的场景也越来越多,本篇文章将介绍如何使用安卓手机与USB设备进行通信。

2 USB简介

USB是英文Universal Serial Bus(通用串行总线)的缩写,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯。是应用在PC领域的接口技术。现在智能手机也加入了对于USB设备的支持。
  安卓手机支持USB accessory模式和USB host模式。USB host模式是手机充当主机,为总线提供电力支持。USB accessory模式正好相反,将手机当作附件把USB设备当作主机。本文中介绍的为Host模式。

3 相关API

class 说明
UsbManager USB管理器,与连接的USB设备通信。
UsbDevice USB设备的抽象,每个UsbDevice都代表一个USB设备。
UsbInterface 定义了设备的功能集,一个UsbDevice可能包含一个或多个UsbInterface,每个Interface都是独立的。
UsbEndpoint UsbEndpoint是Interface的通信通道。
UsbDeviceConnection host与device 建立的连接,并在endpoint 传输数据。
UsbRequest USB 请求包。
UsbConstants USB常量的定义

4 配置AndroidManifest.xml文件

在进行USB开发时,需要在AndroidManifest.xml文件中配置相应的属性。配置代码如下:

<!--添加权限-->
<uses-feature android:name="android.hardware.usb.host"/><activityandroid:name=".MainActivity"android:screenOrientation="landscape"><intent-filter><action android:name="android.intent.action.MAIN" /><!-- 如果这里是启动Activity的话,点击USB接入的弹窗会启动该页面 --><category android:name="android.intent.category.LAUNCHER" /><action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /></intent-filter><meta-dataandroid:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"android:resource="@xml/device_filter" />
</activity>

5 过滤设备

在XML资源文件中,声明要过滤的USB设备的元素。通常,如果要过滤特定设备并使用类,子类和协议(如果要过滤一组USB设备(如大容量存储设备或数码相机)),请使用供应商(vendor-id)和产品(product-id)ID,在开发中这些过滤ID一般可以在文档中找到,或者在设备管理器中查看。
  将资源文件保存在res/xml/目录中。资源文件名(不带.xml扩展名)必须与您在元素中指定的文件名相同。配置格式如下:

<?xml version="1.0" encoding="utf-8"?>
<resources><usb-deviceclass="255"product-id="5678"protocol="1 "subclass="66"vendor-id="1234" />
</resources>

6 监听USB设备的插拔

Android 系统中,USB 设备的插入和拔出是以系统广播的形式发送的,我们只要注册监听这个广播就好。注册广播代码如下:

public class USBReceiver extends BroadcastReceiver {public static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";@Overridepublic 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 (device != null) {//call method to set up device communicationif (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {Log.e("USBReceiver", "获取权限成功:" + device.getDeviceName());} else {Log.e("USBReceiver", "获取权限失败:" + device.getDeviceName());}}}}else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {// 有新的设备插入了,在这里一般会判断这个设备是不是我们想要的,是的话就去请求权限} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {// 有设备拔出了}}
}

7 获取UsbManager

UsbManager类是安卓系统提供的用于管理USB设备的类,其中对于USB设备的操作大多数需要调用此类对象中的方法实现。UsbManager类通过获取系统服务的方式获取。

usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);

8 获取目标UsbDevice

UsbDevice标识着搜索到的USB设备,目标UsbDevice设备需要通过pid和vid进行区别。

/*** @param vendorId  厂商ID* @param productId 产品ID* @return  device*/public UsbDevice getUsbDevice(int vendorId, int productId) {HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();while (deviceIterator.hasNext()) {UsbDevice device = deviceIterator.next();if (device.getVendorId() == vendorId && device.getProductId() == productId) {Log.e("USBUtil", "getDeviceList: " + device.getDeviceName());return device;}}Toast.makeText(context, "没有对应的设备", Toast.LENGTH_SHORT).show();return null;}

9 申请USB设备使用权限

 /*** 判断对应 USB 设备是否有权限*/public boolean hasPermission(UsbDevice device) {return usbManager.hasPermission(device);}/*** 请求获取指定 USB 设备的权限*/public void requestPermission(UsbDevice device) {if (device != null) {if (usbManager.hasPermission(device)) {Toast.makeText(context, "已经获取到权限", Toast.LENGTH_SHORT).show();} else {if (mPermissionIntent != null) {usbManager.requestPermission(device, mPermissionIntent);Toast.makeText(context, "请求USB权限", Toast.LENGTH_SHORT).show();} else {Toast.makeText(context, "请注册USB广播", Toast.LENGTH_LONG).show();}}}}

10 USB设备收发数据

(1)打开通信端口

 public boolean openPort(UsbDevice device) {//获取设备接口,一般只有一个usbInterface = device.getInterface(0);// 判断是否有权限if (hasPermission(device)) {// 打开设备,获取 UsbDeviceConnection 对象,连接设备,用于后面的通讯usbConnection = usbManager.openDevice(device);if (usbConnection == null) {return false;}if (usbConnection.claimInterface(usbInterface, true)) {Toast.makeText(Utils.getContext(), "找到 USB 设备接口", Toast.LENGTH_SHORT).show();} else {usbConnection.close();Toast.makeText(Utils.getContext(), "没有找到 USB 设备接口", Toast.LENGTH_SHORT).show();return false;}} else {Toast.makeText(Utils.getContext(), "没有 USB 权限", Toast.LENGTH_SHORT).show();return false;}//获取接口上的两个端点,分别对应OUT和INfor (int i = 0; i < usbInterface.getEndpointCount(); ++i) {UsbEndpoint end = usbInterface.getEndpoint(i);if (end.getDirection() == UsbConstants.USB_DIR_IN) {usbEndpointIn = end;//获取读入数据的UsbEndpoint} else {usbEndpointOut = end;//获取发送的数据的UsbEndpoint}}return true;}

(2)收发数据
  调用UsbDeviceConnection的bulkTransfer方法与USB设备通信,向USB设备发送数据用usbEndpointOut,接受USB设备的数据用usbEndpointIn。
发送数据:

int ret = usbDeviceConnection.bulkTransfer(usbEndpointOut, data, data.length, 100);

接收数据:
  USB接收数据需开启数据读取线程。

//开线程读取数据
private void startReading() {new Thread(new Runnable() {@Overridepublic void run() {while (isReading) {synchronized (this) {//创建接收数据的数组byte[] data = new byte[usbEndpointIn.getMaxPacketSize()];//读取数据int ret = usbConnection.bulkTransfer(usbEndpointIn, data, data.length, 100);   }}}}).start();
}

11 结语

安卓USB通信具有即插即用,可热插拔,具有自动配置能力,用户只要简单地将外设插人到手机就能自动识别和配置USB设备。目前安卓手机、平板都具备USB接口,连接灵活,易扩展。
  USB通信速率相对较快,USB2.0理论速度约每秒480Mbps(约每秒60MB),USB3.0的理论速度能够达到每秒5Gbps(约为每秒625MB)。
  

针对Android程序员,除了上面的知识体系,我也分享一份私货,分享我从网络上收录整理的 Android学习PDF+架构视频+面试文档+源码笔记 ,还有Android开发面试专题资料,高级进阶架构资料供大家学习进阶
免费获取学习资料可以进群找我:434543138。

干货分享——安卓USB通信相关推荐

  1. codesys中打开linux端的串口_干货分享——安卓串口通信

    1 引言 串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件.串口通信(Serial Communicatio ...

  2. 安卓USB通信之权限管理

    这篇博客是针对之前的一篇文章Android开发之USB数据通信作的补充.主要是在开发中发现了另外两个不得不面对的问题: USB访问权限处理. USB设备插拔状态监听. -USB访问权限处理--- 当我 ...

  3. 干货分享:RS485通信和Modbus通信协议汇总

    https://zhuanlan.zhihu.com/p/24134130 在工业控制.电力通讯.智能仪表等领域,通常情况下是采用串口通信的方式进行数据交换.最初采用的方式是RS232接口,由于工业现 ...

  4. 干货分享|巧用CSS滤镜绘制安卓手机充电动效(uni-app|view组件版)

    前言 CSS3的滤镜真的是一个非常强大的功能,如果我们能够很好的利用它,并充分发挥我们的想象力,想要制作出非常惊艳的动效也是没有问题的哦.比如:接下来我要跟大家分享的一个巧妙使用CSS滤镜绘制出来的a ...

  5. 干货分享 | 自然语言处理及词向量模型介绍(附PPT)

    云脑科技机器学习训练营第二期,对自然语言处理及词向量模型进行了详细介绍,量子位作为合作媒体为大家带来本期干货分享~ 本期讲师简介 樊向军 云脑科技核心算法工程师,清华大学学士,日本东京大学与美国华盛顿 ...

  6. 如何快速全面建立自己的大数据知识体系? 大数据 ETL 用户画像 机器学习 阅读232 作者经过研发多个大数据产品,将自己形成关于大数据知识体系的干货分享出来,希望给大家能够快速建立起大数据

    如何快速全面建立自己的大数据知识体系? 大数据 ETL 用户画像 机器学习 阅读232  作者经过研发多个大数据产品,将自己形成关于大数据知识体系的干货分享出来,希望给大家能够快速建立起大数据产品的体 ...

  7. eureka 之前的服务如何关闭_干货分享 | 服务注册中心Spring Cloud Eureka部分源码分析...

    友情提示:全文13000多文字,预计阅读时间10-15分钟 Spring Cloud Eureka作为常用的服务注册中心,我们有必要去了解其内在实现机制,这样出现问题的时候我们可以快速去定位问题.当我 ...

  8. 安卓USB开发教程 一 USB Host 与 Accessory

    安卓通过两种模式:USB Accessory 与 USB Host 模式支持多种 USB 外设与安卓 USB 配件(实现安卓配件协议的硬件).在 USB 配件模式下,外部 USB 硬件充当 USB 主 ...

  9. uds下载服务流程图_UDS诊断全集,干货分享

    UDS诊断是Unified Diagnostic Services的全称,其标准是ISO14229,ISO15765,文末可获取链接. 其中: ISO14229-1定义了各诊断服务的格式,以及一些通用 ...

  10. 【安卓USB开发】让手机与物联网设备鹊桥相会

    安卓USB开发详解 一.前言 1.是什么 2.为什么 3.怎么做 二.简析USB 1.外部总线标准 2.主从结构星型拓扑 3.自.总供电模式 4.OTG 5.数据传输模式 6.小结 三.安卓USB开发 ...

最新文章

  1. String[] arrayIP= null;的典型错误
  2. 利用OpenCV进行边缘检测
  3. 特斯拉与Mobileye口水战的背后,是自动驾驶技术话语权之争
  4. OpenGL 光照贴图Lighting maps
  5. 初级前端工程师笔试技巧总结,祝你顺利拿高分
  6. android 跳转页面出错,Android 页面跳转(无/含有返回结果)
  7. python基础课程5(看代码看注释)--numpy
  8. EOS开发dApp前需要了解的五件事
  9. 朴素贝叶斯文本分类代码(详解)
  10. 分享吴恩达机器学习视频和300页word学习笔记,以及深度学习五门课视频及700页word笔记
  11. win10关闭windows聚焦_关于Windows 10 Windows聚焦功能失效
  12. Spring Boot 整合 Thymeleaf 完整 Web 案例
  13. 金融行业基于 DELL EMC 高端存储的核心系统实践经验分享
  14. 群晖7.0搭建discuz论坛
  15. windows如何调出不见的语言栏
  16. 北京农学院计算机调剂,2020北京农学院植物科学技术学院招收硕士研究生调剂...
  17. 使用Senparc.Weixin SDK搭建微信公众号服务程序
  18. 零知识证明:Sigma协议
  19. 六大设计原则-接口隔离原则
  20. Mac 设置允许任何来源软件运行

热门文章

  1. 使用虚幻4进行安卓打包
  2. modbus tcp调试助手_wemos D1 arduino项目实战1-TCP协议连接Tlink平台①
  3. 高速PCB设计的一些注意事项
  4. MATLAB —— 散点图绘制
  5. 如何找回QQ聊天记录、语音、图片?
  6. Mathematica图像处理
  7. Java利用poi-tl实现富文本HTML转Word
  8. 3dmax渲染出来的图不清晰?
  9. Linux PTP IEEE1588使用
  10. python3.9.0a2怎么安装pygame_Python自学——pygame安装