干货分享——安卓USB通信
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通信相关推荐
- codesys中打开linux端的串口_干货分享——安卓串口通信
1 引言 串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件.串口通信(Serial Communicatio ...
- 安卓USB通信之权限管理
这篇博客是针对之前的一篇文章Android开发之USB数据通信作的补充.主要是在开发中发现了另外两个不得不面对的问题: USB访问权限处理. USB设备插拔状态监听. -USB访问权限处理--- 当我 ...
- 干货分享:RS485通信和Modbus通信协议汇总
https://zhuanlan.zhihu.com/p/24134130 在工业控制.电力通讯.智能仪表等领域,通常情况下是采用串口通信的方式进行数据交换.最初采用的方式是RS232接口,由于工业现 ...
- 干货分享|巧用CSS滤镜绘制安卓手机充电动效(uni-app|view组件版)
前言 CSS3的滤镜真的是一个非常强大的功能,如果我们能够很好的利用它,并充分发挥我们的想象力,想要制作出非常惊艳的动效也是没有问题的哦.比如:接下来我要跟大家分享的一个巧妙使用CSS滤镜绘制出来的a ...
- 干货分享 | 自然语言处理及词向量模型介绍(附PPT)
云脑科技机器学习训练营第二期,对自然语言处理及词向量模型进行了详细介绍,量子位作为合作媒体为大家带来本期干货分享~ 本期讲师简介 樊向军 云脑科技核心算法工程师,清华大学学士,日本东京大学与美国华盛顿 ...
- 如何快速全面建立自己的大数据知识体系? 大数据 ETL 用户画像 机器学习 阅读232 作者经过研发多个大数据产品,将自己形成关于大数据知识体系的干货分享出来,希望给大家能够快速建立起大数据
如何快速全面建立自己的大数据知识体系? 大数据 ETL 用户画像 机器学习 阅读232 作者经过研发多个大数据产品,将自己形成关于大数据知识体系的干货分享出来,希望给大家能够快速建立起大数据产品的体 ...
- eureka 之前的服务如何关闭_干货分享 | 服务注册中心Spring Cloud Eureka部分源码分析...
友情提示:全文13000多文字,预计阅读时间10-15分钟 Spring Cloud Eureka作为常用的服务注册中心,我们有必要去了解其内在实现机制,这样出现问题的时候我们可以快速去定位问题.当我 ...
- 安卓USB开发教程 一 USB Host 与 Accessory
安卓通过两种模式:USB Accessory 与 USB Host 模式支持多种 USB 外设与安卓 USB 配件(实现安卓配件协议的硬件).在 USB 配件模式下,外部 USB 硬件充当 USB 主 ...
- uds下载服务流程图_UDS诊断全集,干货分享
UDS诊断是Unified Diagnostic Services的全称,其标准是ISO14229,ISO15765,文末可获取链接. 其中: ISO14229-1定义了各诊断服务的格式,以及一些通用 ...
- 【安卓USB开发】让手机与物联网设备鹊桥相会
安卓USB开发详解 一.前言 1.是什么 2.为什么 3.怎么做 二.简析USB 1.外部总线标准 2.主从结构星型拓扑 3.自.总供电模式 4.OTG 5.数据传输模式 6.小结 三.安卓USB开发 ...
最新文章
- String[] arrayIP= null;的典型错误
- 利用OpenCV进行边缘检测
- 特斯拉与Mobileye口水战的背后,是自动驾驶技术话语权之争
- OpenGL 光照贴图Lighting maps
- 初级前端工程师笔试技巧总结,祝你顺利拿高分
- android 跳转页面出错,Android 页面跳转(无/含有返回结果)
- python基础课程5(看代码看注释)--numpy
- EOS开发dApp前需要了解的五件事
- 朴素贝叶斯文本分类代码(详解)
- 分享吴恩达机器学习视频和300页word学习笔记,以及深度学习五门课视频及700页word笔记
- win10关闭windows聚焦_关于Windows 10 Windows聚焦功能失效
- Spring Boot 整合 Thymeleaf 完整 Web 案例
- 金融行业基于 DELL EMC 高端存储的核心系统实践经验分享
- 群晖7.0搭建discuz论坛
- windows如何调出不见的语言栏
- 北京农学院计算机调剂,2020北京农学院植物科学技术学院招收硕士研究生调剂...
- 使用Senparc.Weixin SDK搭建微信公众号服务程序
- 零知识证明:Sigma协议
- 六大设计原则-接口隔离原则
- Mac 设置允许任何来源软件运行