Android USB 开发详解
Android USB 开发详解
先附上 Android USB 官方文档
Android通过两种模式支持各种 USB 外设和 Android USB 附件(实现Android附件协议的硬件):USB附件和USB主机。USB开发需 Android 3.1(API级别12)以上。由于本人工作中只用到了主机模式,所以本文的侧重点在主机模式开发。
- Android USB 开发详解
- 调试
- 一、AndroidManifest 文件设置
- 二、USB 设备的连接和使用
- 1.Android 中的 USB
- 2.USB 设备的插入
- 3.获取 UsbManager
- 4.获取 USB 设备列表
- 5.获取特定的设备
- 6.申请 USB 设备使用权限
- 7.通信
- 其他
调试
在使用 USB 连接设备调试的时候,USB 外设将不能连接至设备,可以使用 WIFI 的方式连接调试,settings -> plugin -> WiFi ADB 插件好几个,选个适合自己的就 OK。
或者…我这里正好有一篇Android 模拟器连接 USB 设备喜欢点个赞哈!
一、AndroidManifest 文件设置
- uses-feature 申明这个软件需要使用 USB 功能,申明这个 Google Play 会把不满足的设备过滤掉,一般用 USB 的都是定制开发,忽略就行
<uses-feature android:name="android.hardware.usb.host"/>
- 1
- 将应用程序的最低SDK设置为API级别12或更高,早期 API 没有。
- 如果你希望你的应用程序连接指定的 USB 设备时被通知,需指定 和 元素对用于 android.hardware.usb.action.USB_DEVICE_ATTACHED。该 元素指向声明识别有关您要检测的设备信息的外部XML资源文件。
<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>
- 在XML资源文件中,声明要过滤的USB设备的元素。以下列表描述了属性 。通常,如果要过滤特定设备并使用类,子类和协议(如果要过滤一组USB设备(如大容量存储设备或数码相机)),请使用供应商(vendor-id)和产品(product-id)ID,在开发中这些过滤ID一般可以在文档中找到,或者自己连上看也行。你可以指定部分或全部这些属性。
将资源文件保存在res/xml/目录中。资源文件名(不带.xml扩展名)必须与您在元素中指定的文件名相同 。对于XML资源文件格式的 例子如下:
<?xml version="1.0" encoding="utf-8"?>
<resources><usb-deviceclass="255"product-id="5678"protocol="1 "subclass="66"vendor-id="1234" />
</resources>
配置好清单文件后当用户连接与您的设备过滤器匹配的设备时,系统会向他们显示一个对话框,询问他们是否要启动您的应用程序。如果用户接受,则应用程序将自动具有访问设备的权限,直到设备断开连接。如果给了默认,那么这个 USB 设备插入后会自动启动这个 Activity
二、USB 设备的连接和使用
在清单文件中配置好以后我们直接进入 Java 代码环节
1.Android 中的 USB
Android 3.1(API级别12)以上原生提供了 USB 开发的 API,在android.hardware.usb包下提供了开发的相关类。
Class | 说明 |
---|---|
UsbManager | 获得 USB 管理器,与连接的 USB 设备通信。 |
UsbDevice | USB 设备的抽象,每个UsbDevice 都代表一个 USB 设备。 |
UsbInterface | 定义了设备的功能集,一个 UsbDevice 可能包含一个或多个UsbInterface,每个 Interface 都是独立的。 |
UsbEndpoint | UsbEndpoint 是 interface 的通信通道。 |
UsbDeviceConnection | host 与 device 建立的连接,并在 endpoint 传输数据。 |
UsbRequest | USB 请求包。 |
UsbConstants | USB 常量的定义 |
2.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)) {// 有设备拔出了}}
}
3.获取 UsbManager
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
4.获取 USB 设备列表
public List<UsbDevice> getDeviceList() {HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();List<UsbDevice> usbDevices = new ArrayList<>();while (deviceIterator.hasNext()) {UsbDevice device = deviceIterator.next();usbDevices.add(device);Log.e("USBUtil", "getDeviceList: " + device.getDeviceName());}return usbDevices;}
5.获取特定的设备
/*** mVendorId=1137,mProductId=85 佳博 3150T 标签打印机** @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;}
6.申请 USB 设备使用权限
安卓系统对 USB 设备的使用需要得到相应的权限,这个权限要用户手动授予,或插入设备时应用到你的应用中。在使用 USB 设备前首先我们要确认一下上一节中的device是否已经获得权限,如果没有就要主动申请权限:
/*** 判断对应 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();}}}}
注册广播:
public void registerReceiver(Activity context) {mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);context.registerReceiver(usbReceiver, filter);}
7.通信
与 USB 设备的通信可以是同步的也可以是异步的。无论哪种情况,你都应该创建一个新线程来执行所有数据传输,避免阻塞UI线程。
第一步,打开通信端口
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;} else {usbEndpointOut = end;}}return true;}
第二步,发送数据
usbConnection.bulkTransfer(usbEndpointOut, bytes, bytes.length, 500);
其他
剩余的 API 我会在项目不断完善的同时更新上来
Android USB 开发详解相关推荐
- 《Android游戏开发详解》——第1章,第1.6节函数(在Java中称为“方法”更好)...
本节书摘来自异步社区<Android游戏开发详解>一书中的第1章,第1.6节函数(在Java中称为"方法"更好),作者 [美]Jonathan S. Harbour,更 ...
- JMessage Android 端开发详解
JMessage Android 端开发详解 目前越来越多的应用会需要集成即时通讯功能,这里就为大家详细讲一下如何通过集成 JMessage 来为你的 App 增加即时通讯功能. 首先,一个最基础的 ...
- 《Android游戏开发详解》一2.16 区分类和对象
本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.16节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社 ...
- 《Android游戏开发详解》一3.1 构造方法
本节书摘来异步社区<Android游戏开发详解>一书中的第3章,第3.1节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区 ...
- 《Android游戏开发详解》一导读
前 言 Android游戏开发详解 作为对编程知之甚少或者毫无所知的初学者,开始学习Android游戏开发,可能会觉得就像是穿越陌生的星际的旅程.有太多的事情要尝试,太多的知识要学习,令人遗憾的是,还 ...
- 《Android游戏开发详解》——第3章,第3.1节构造方法
本节书摘来自异步社区<Android游戏开发详解>一书中的第3章,第3.1节构造方法,作者 [美]Jonathan S. Harbour,更多章节内容可以访问云栖社区"异步社区& ...
- 《Android游戏开发详解》一2.18 使用Java API中的对象
本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.18节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 2.1 ...
- 《Android游戏开发详解》——第2章,第2.10节使用对象
本节书摘来自异步社区<Android游戏开发详解>一书中的第2章,第2.10节使用对象,作者 [美]Jonathan S. Harbour,更多章节内容可以访问云栖社区"异步社区 ...
- 《Android游戏开发详解》一2.2 设置开发机器
本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.2节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区 ...
最新文章
- React + Threejs + Swiper 实现全景图效果
- python123 https://github.com/jackfrued/Python-100-Days/tree/master/Day01-15
- 动态数组 allocator
- myeclipse配置weblogicserver
- js弹出窗体获得焦点
- MyEclipse2015双击不能打开文件
- 最大值减最小值等于区间长度_呆哥数学每日一题 ——三角函数求余弦最小值...
- Altium Designer20 PCB板子绘制
- SQL存储过程调试方法
- 潭州课堂25班:Ph201805201 django 项目 第二十四课 文章主页 多级评论数据库设计 ,后台代码完成 (课堂笔记)...
- cms文章 mysql存储_MySQL存储引擎笔记
- 玩转spring boot——开篇
- 我是如何用redis做实时订阅推送的
- kali netstat使用教程
- k开头的英文单词计算机专业,以K开头的英语单词
- 使用vue+div+svg实现审批流程图功能,可生成JSON格式
- 英语字母表及其冠词用法
- win10系统怎么连接蓝牙耳机 旧时光 oldtimeblog
- lamp mysql什么意思_什么是lampapache+mysql+php
- Android 桌面图标添加未读消息角标APP角标最佳实践
热门文章
- python学习-元组tuple(定义、删除、长度、复制、查找、遍历、operator,和列表的区别)
- java实现可视化报表_如何在Power BI中记录报表可视化?
- php使用pdf2htmlex,转换 HTML 与 PDF 格式文档的神器
- html表格美化代码,分享:记录一次使用纯CSS美化table表格的代码
- android字体显示不全,android 按钮的文字显示不全
- jrtplib 打包做了哪些事_30岁前就实现财务自由的人,都做了哪些事
- python中curve fit_在python中拟合多变量curve_fit
- 中国深圳,600架无人机的盛典!
- 【第二期】那些设计漂亮、有创意的电路板!
- java nanotime 重复_Java中System.nanoTime方法能作为一个唯一字符串来使用吗