硬件交互的首篇对设备硬件的分类中,互联通信系列硬件主要用来与其他设备进行数据交互。从本文开始,将重点介绍该系列相关硬件。

互联通信系列硬件

根据硬件的可通信距离,由近及远分为USB、NFC、蓝牙、WLAN,SIM卡槽,这些硬件之间的功能原理及关系可以查找其他资料详细学习。总之,他们为当前设备与其他设备的交互搭建了桥梁,只要双方设备均遵循该系列硬件的协议,就可以在硬件层互相通信,而设备上的Android操作系统便会将硬件层的数据转换为应用层数据,进而与应用程序交互。这样也就实现了两个不同设备上的应用程序间的交互方案。理论上这个方案是可行的,那实际各硬件的使用方式分别是怎么样的呢?

USB接口

在应用程序中与USB硬件的交互,系统提供了两种方式,包括将该应用程序所在设备的USB接口作为主机模式,和该应用程序所在设备的USB接口作为配件模式。在主机模式下,该应用程序所在设备通过USB接口为其他接入的USB设备供电,通常连接没有自带电源的设备(比如U盘)时启用此种模式;反之在配件模式下,是该应用程序所在设备接收通过USB接口接入的其他USB设备的电源提供,通常在连接有电源的设备(比如笔记本电脑)时启用此模式。理论上这两种模式只是针对USB硬件的供电方不同而区分,均可以在USB接口连接的两个设备之间的数据传输。

主机模式

权限声明

在应用程序的清单文件中,需要声明<uses-feature />标签,并设置其属性android:name值为"android.hardware.usb.host"。该标签设置并不是通过应用程序向系统申请权限,而是声明应用程序需要使用USB主机模式。

使用流程
获取USB主机设备

主机模式下,其中一种常用情况,应用程序可以监听插入USB接口的设备,此时可以在需要监听的界面Activity对应的清单文件注册信息中增加指定的接收意图,意图值为android.hardware.usb.action.USB_DEVICE_ATTACHED。这样在USB设备接入后,系统会发送上述意图值的广播,从而启动当前界面Activity

在启动后的界面Activity中,可以调用getIntent().getParcelableExtra(UsbManager.EXTRA_DEVICE)系列方法,获取android.hardware.usb.UsbDevice USB设备类的对象。

主机模式下另外一种情况,是直接获取已连接的USB设备。在能获取上下文环境Context对象的地方,调用该对象的getSystemService(String name),并指定参数值 nameContext.USB_SERVICE="usb",获得android.hardware.usb.UsbManagerUSB管理类的对象。调用该对象的getDeviceList()方法,返回List<UsbDevice>,同样能获取到当前设备连接的所有USB硬件对象的列表数据。

在直接获取已连接USB设备的情况下,应用程序需要主动向用户申请设备通信权限。通过USBManager设备管理类对象的requestPermission(UsbAccessory accessory, PendingIntent pi)方法,在用户同意授权后,才能继续后续设备通信操作。

USB设备通信

在拿到UsbDevice类型的USB设备类对象,和UsbManager管理类对象之后,调用USB管理类对象的openDevice(UsbDevice device)方法,得到android.hardware.usb.UsbDeviceConnection USB设备连接对象,其参数 device 便是要通信的USB设备对象。

建立UsbDeviceConnection设备连接对象后,通信过程中还需要分别借助android.hardware.usb.UsbInterface USB接口类和android.hardware.usb.UsbEndpoint USB端点类。

在获取UsbDevice类型的设备类对象后,调用其getInterface(int index)方法获取UsbInterfaceUSB接口类对象,其中参数 index 是当前USB设备可获取的所有接口数量中的索引值,而获取UsbDevice的所有接口数量,可根据另外一个方法getInterfaceCount()查看。

在获取UsbInterface类型的接口对象后,调用其getEndpoint(int index)方法获取UsbEndpointUSB端点类对象,其中参数 index 是当前USB接口中可获取的所有断点数量中的索引值,而获取UsbInterface的所有断点数量,可根据另外一个方法getEndpointCount()查看。

通过梅开二度获取USB接口对象和USB端点对象之后,首先要占用USB设备资源。继续调用UsbDeviceConnection连接对象的claimInterface(UsbInterface intf, boolean force)方法,其中参数 intf 便是上文获取UsbInterface接口类对象,参数 force 标明是否强制占用。返回boolean类型的结果表示占用是否成功。

在占用USB设备资源之后,就可以接收USB设备的通信数据了。调用UsbDeviceConnection连接对象的bulkTransfer (UsbEndpoint endpoint, byte[] buffer, int offset, int length, int timeout)方法。参数 endpoint 便是上文获取UsbEndpoint端点类对象;参数 buffer 用以存储通信中的二进制数组;参数 offset 可选项,默认值为0,用以标记存放数组 buffer 的起始位置;参数 length 用以标记存放数组的长度;参数 timeout 作为通信连接的最大时长。返回通信过程中实际传输的数据长度。

通信结束后,只需要关闭连接并释放占用的设备资源。调用UsbDeviceConnection连接对象的close()方法可以关闭通信连接。而调用该对象的releaseInterface(UsbInterface intf)方法可以释放占用的UsbInterface设备接口类型的参数 intf 对象。

配件模式

权限声明

在应用程序的清单文件中,需要声明<uses-feature />标签,并设置其属性android:name值为"android.hardware.usb.accessory"。该标签设置并不是通过应用程序向系统申请权限,而是声明应用程序需要使用USB配件模式。

使用流程
获取USB配件

配件模式下,其中一种常用情况,应用程序可以监听插入USB接口的设备,此时可以在需要监听的界面Activity对应的清单文件注册信息中增加指定的接收意图,意图值为android.hardware.usb.action.USB_ACCESSORY_ATTACHED。这样在USB设备接入后,系统会发送上述意图值的广播,从而启动当前界面Activity

在启动后的界面Activity中,可以调用getIntent().getParcelableExtra(UsbManager.EXTRA_ACCESSORY)系列方法,获取android.hardware.usb.UsbAccessory USB配件类的对象。

同样在配件模式下另外一种情况,是直接获取已连接的USB配件。在能获取上下文环境Context对象的地方,调用该对象的getSystemService(String name),并指定参数值 nameContext.USB_SERVICE="usb",获得android.hardware.usb.UsbManagerUSB管理类的对象。调用该对象的getAccessoryList()方法,返回List<UsbAccessory>,同样能获取到当前设备连接的所有USB配件对象的列表数据。

与主机模式类似,在直接获取已连接USB配件的情况下,应用程序需要主动向用户申请设备通信权限。通过USBManager设备管理类对象的requestPermission(UsbAccessory accessory, PendingIntent pi)方法,在用户同意授权后,才能继续后续设备通信操作。

USB设备通信

在拿到UsbAccessory类型的USB配件类对象,和UsbManager管理类对象之后,调用USB管理类对象的openAccessory(UsbAccessory accessory)方法,得到android.os.ParcelFileDescriptor 数据流化的文件描述符类的对象,其参数 accessory 便是要通信的USB配件对象。

在获取ParcelFileDescriptor数据流化的文件描述符类的对象后,调用其getFileDescriptor()方法得到java.io.FileDescriptor普通的文件描述符类型的对象,之后通过该对象创建基本的文件输入流java.io.FileInputStream对象以读取USB配件中的数据,或者创建基本的文件输出流java.io.FileOutputStream对象以将数据写入USB配件中。

通信结束后,只需要关闭数据流化的文件描述符的占用即可。通过调用ParcelFileDescriptor对象的close()方法以实现该操作。

主机模式与配件模式的区别

代码软件层

主机模式下,主要使用UsbDevice类,可以获取所连接USB设备的详细信息。

配件模式下,只能使用UsbAccessory类,只能获取连接USB设备的基本信息。

硬件层

主机模式下,由应用程序所在的设备向主线供电,并向连接的USB设备供电。

配件模式下,由连接的USB设备作为主机向主线供电,并向应用程序所在的设备供电。

Android系统编程入门系列之硬件交互——通信硬件USB的更多相关文章

  1. Android系统编程入门系列之加载界面Activity

    上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...

  2. Android系统编程入门系列之硬件交互——多媒体摄像头

    多媒体系列硬件 多媒体包括图片.动画.音频.视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件.当然随着硬件 ...

  3. Android系统编程入门系列之硬件交互——传感器

    到目前为止,关于应用程序与用户之间的相关内容便比较肤浅的大致介绍完毕.而在整个系统架构中,应用程序与用户之间的交互,犹如参天大树上的枝干和树叶,交互起来五彩缤纷,但使整个生态系统保持生命力的核心,在于 ...

  4. Android系统编程入门系列之硬件交互——通信硬件Bluetooth

    通信硬件NFC的文章,虽然可以在Android系统中通过非直接接触的形式与支持NFC硬件的设备通信,但是也只能交互一些简短的标签内容,对大量的持续性数据,却并不能很好的支持.因此针对这个弊端,可以考虑 ...

  5. Android系统编程入门系列之硬件交互——多媒体展示

    前两篇文章通过麦克风硬件和摄像头硬件分别采集音频和视频的多媒体数据,在得到的多媒体数据通常是以编码文件的格式存储,在用户需要展示时,可通过设备的内置扩音器或蓝牙耳机等硬件播放音频,通过设备的显示屏或外 ...

  6. Android系统编程入门系列之硬件交互——通信硬件NFC

    在上篇文章介绍了接入式USB硬件的简单使用,接下来将介绍不依赖物理连接的硬件通信了.本文的重点是近距离通信的硬件NFC. NFC硬件 应用程序中可以通过NFC硬件读取或发送指定协议的技术实现,在And ...

  7. Android系统编程入门系列之硬件交互——无线通信WLAN

    Android系统的移动设备大多支持无线WLAN技术.利用该技术,不仅能实现互联网通信,还能实现无线定位,热点共享等远程通信功能.针对使用WLAN的不同功能,可能需要分别申请不同的权限声明,同时调用不 ...

  8. Android系统编程入门系列之硬件交互——通信硬件电信SIM卡

    现在的SIM卡通常具备基站定位.语音通话.短信消息.网络流量这四大功能,而在移动端是无法对SIM卡使用基站定位功能的,所以这里只介绍移动端如何使用SIM卡实现语音通话.短信消息.数据流量三个功能. 语 ...

  9. Android系统编程入门系列之界面Activity交互响应

    在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸操作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应.本文 ...

随机推荐

  1. 【Linux】【Services】【SaaS】Docker+kubernetes(11. 构建复杂的高可用网络)

    1. 简介 flannel在实战阶段貌似不能胜任在灾难恢复时候异地的网络,打算用openvswith试试

  2. vue cli3.0 首次加载优化

    项目经理要求做首页加载优化,打包后从十几兆优化到两兆多,记下来怕下次忘记 运行report脚本 可看到都加载了那些内容,在从dist文件中index.html 查看首次加载都加载了那些东西,如下图:然 ...

  3. 1、Redis简介

    一.NOSQL 1.什么是NOSQL? NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL". 指的是非关系型的数据库.NoSQL有时也称作Not On ...

  4. pipeline input步骤

    目录 一.简介 二.input步骤复杂用法 三.获取上游pipeline信息 四.超时中止 一.简介 执行imput步骤会暂停pipeline,直到用户输入参数.这是一种特殊的参数化pipeline的 ...

  5. GraphQL 到底有什么魔力?

    时间退回到 2012年的一个下午, 美国加利福尼亚州, facebook 的工程师们发现他们才上架没多久的移动端应用就收到了很多差评, 用户反映app响应慢,耗电严重等,经过分析后发现, 应用在第一次 ...

  6. 【二进制】【WP】MOCTF逆向题解

    moctf 逆向第一题:SOEASY 这个是个 64 位的软件,OD 打不开,只能用 IDA64 打开,直接搜字符串(shift+F12)就可以看到 moctf 逆向第二题:跳跳跳 这个题当初给了初学 ...

  7. python enumerate枚举用法总结

    enumerate()说明 enumerate()是python的内置函数enumerate在字典上是枚举.列举的意思对于一个可迭代的(iterable)/可遍历的对象(如列表.字符串),enumer ...

  8. jquery autocomplete 插件的使用

    Autocomplete 自动完成 功能:输入框在输入关键字后,根据输入的内容给出相关的下拉框供用户选择,自动完成输入内容. 插件:使用jqueryUI的自动完成小部件,文档地址:https://jq ...

  9. SpringBoot结果集包装类

    1.前言 在SpringBoot项目中.看了一部分代码.发现一般的接口以JSON形式返回最佳.接口规范遵照RESTFUL风格来写.返回的结果集呢.借助包装类来包装.这样有利于前后端的交互.写出来的代码 ...

  10. 钉钉提供的内网穿透之HTTP穿透

    此方法无需自行提供服务器和域名 官方地址:https://developers.dingtalk.com/document/resourcedownload/http-intranet-penetra ...