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 开发详解相关推荐

  1. 《Android游戏开发详解》——第1章,第1.6节函数(在Java中称为“方法”更好)...

    本节书摘来自异步社区<Android游戏开发详解>一书中的第1章,第1.6节函数(在Java中称为"方法"更好),作者 [美]Jonathan S. Harbour,更 ...

  2. JMessage Android 端开发详解

    JMessage Android 端开发详解 目前越来越多的应用会需要集成即时通讯功能,这里就为大家详细讲一下如何通过集成 JMessage 来为你的 App 增加即时通讯功能. 首先,一个最基础的 ...

  3. 《Android游戏开发详解》一2.16 区分类和对象

    本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.16节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社 ...

  4. 《Android游戏开发详解》一3.1 构造方法

    本节书摘来异步社区<Android游戏开发详解>一书中的第3章,第3.1节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区 ...

  5. 《Android游戏开发详解》一导读

    前 言 Android游戏开发详解 作为对编程知之甚少或者毫无所知的初学者,开始学习Android游戏开发,可能会觉得就像是穿越陌生的星际的旅程.有太多的事情要尝试,太多的知识要学习,令人遗憾的是,还 ...

  6. 《Android游戏开发详解》——第3章,第3.1节构造方法

    本节书摘来自异步社区<Android游戏开发详解>一书中的第3章,第3.1节构造方法,作者 [美]Jonathan S. Harbour,更多章节内容可以访问云栖社区"异步社区& ...

  7. 《Android游戏开发详解》一2.18 使用Java API中的对象

    本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.18节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 2.1 ...

  8. 《Android游戏开发详解》——第2章,第2.10节使用对象

    本节书摘来自异步社区<Android游戏开发详解>一书中的第2章,第2.10节使用对象,作者 [美]Jonathan S. Harbour,更多章节内容可以访问云栖社区"异步社区 ...

  9. 《Android游戏开发详解》一2.2 设置开发机器

    本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.2节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区 ...

最新文章

  1. React + Threejs + Swiper 实现全景图效果
  2. python123 https://github.com/jackfrued/Python-100-Days/tree/master/Day01-15
  3. 动态数组 allocator
  4. myeclipse配置weblogicserver
  5. js弹出窗体获得焦点
  6. MyEclipse2015双击不能打开文件
  7. 最大值减最小值等于区间长度_呆哥数学每日一题 ——三角函数求余弦最小值...
  8. Altium Designer20 PCB板子绘制
  9. SQL存储过程调试方法
  10. 潭州课堂25班:Ph201805201 django 项目 第二十四课 文章主页 多级评论数据库设计 ,后台代码完成 (课堂笔记)...
  11. cms文章 mysql存储_MySQL存储引擎笔记
  12. 玩转spring boot——开篇
  13. 我是如何用redis做实时订阅推送的
  14. kali netstat使用教程
  15. k开头的英文单词计算机专业,以K开头的英语单词
  16. 使用vue+div+svg实现审批流程图功能,可生成JSON格式
  17. 英语字母表及其冠词用法
  18. win10系统怎么连接蓝牙耳机 旧时光 oldtimeblog
  19. lamp mysql什么意思_什么是lampapache+mysql+php
  20. Android 桌面图标添加未读消息角标APP角标最佳实践

热门文章

  1. python学习-元组tuple(定义、删除、长度、复制、查找、遍历、operator,和列表的区别)
  2. java实现可视化报表_如何在Power BI中记录报表可视化?
  3. php使用pdf2htmlex,转换 HTML 与 PDF 格式文档的神器
  4. html表格美化代码,分享:记录一次使用纯CSS美化table表格的代码
  5. android字体显示不全,android 按钮的文字显示不全
  6. jrtplib 打包做了哪些事_30岁前就实现财务自由的人,都做了哪些事
  7. python中curve fit_在python中拟合多变量curve_fit
  8. 中国深圳,600架无人机的盛典!
  9. 【第二期】那些设计漂亮、有创意的电路板!
  10. java nanotime 重复_Java中System.nanoTime方法能作为一个唯一字符串来使用吗