Android USB配件模式
原文:http://android.eoe.cn/topic/android_sdk
USB配件模式允许用户连接那些专门搭载Android设备的USB主机硬件。这些配件必须遵守Android配件开发工具包文档中所列出的Android附件协议。这使得搭载Android系统的设备在不充当USB主机的情况之下,仍然可以和USB硬件进行交互。当一台搭载Android系统的设备处于USB配件模式时,所依附的Android USB配件作为主机为USB总线提供能源以及列举出相连的设备。Android3.1(API12级)提供了USB配件模式并且这一特点也继承了Android2.3.4(API10级)以此来支持更多设备。
选择正确的USB附件APIs
尽管USB附件API在Android3.1平台才开始介绍,但是也可以在Android2.3.4API中通过附加类库使用。因为这些APIs都是通过额外的类库来使用的,你可以导入两个包来支持USB配件模式。取决于你想支持什么样的搭载Android系统的设备,你也许不得不在一个的基础上使用另外一个:
com.android.feature.usb:为了支持Android2.3.4的USB配件模式,Google APIs附加类库包括了USB外设APIs并且它们就是包含在这个命名空间的后面。Android3.1还支持导入和调用这个命名空间的类来支持附加类库编写的应用程序。这个附加的类库只是关于android.hardware.usb外设APIs的一个简单的封装并且它不支持USB主机模式。如果你希望更大范围支持USB配件模式的设备,使用附加类库并且导入改包就行。需要注意的是,并不是所有搭载Android2.3.4的设备都需要拥有USB外设这一特色。每个设备生产商在决定是否具有这个特色,这也就是为什么你必须要在manifest文件中声明的原因了。
android.hardware.usb:这个命名空间包含在Android3.1版本中支持USB附件模式的类。因为这个包是框架APIs中的一部分,所以Android3.1版本可以在不用附加类库的前提之下支持USB附件模式。使用这个包时,如果你只关心Android3.1或者更新的支持USB附件模式的硬件的设备,你可以在mainfest文件中进行声明。
安装谷歌APIs的附加类库
如果你想安装这个附加类库,你可以通过在SDK管理器上面安装谷歌APIs中的Android API10包的方式来做。更多关于安装附加类库的信息请参见安装谷歌APIs附加元件。
API 概述
因为附加类库是一个框架APIs的封装,和那些支持USB附件功能的类是相似的。即使你在用附加类库的时候,你也可以用android.hardware.usb参考文档作为参考。
* 注意:* 然而,你要注意在附加类库和框架APIs之间还是有一些细微的使用差别的。
下面的表格为您描述了那些支持USB外设APIs的类:
{|style="border-spacing: 0px;margin: 4px 4px; width: 90%; border-left:1px solid #ccc;border-top:1px solid #ccc
|-style="background:#DEE8F1; "
! style="border-right:1px solid #ccc;border-bottom:1px solid #ccc; padding:5px 15px" | 类
! style="border-right:1px solid #ccc;border-bottom:1px solid #ccc; padding:5px 15px" | 详细描述
|- style=" vertical-align:top;"
| style=" border-right:1px solid #ccc;border-bottom:1px solid #ccc; padding:5px 15px; " |
UsbManager
| style="border-right:1px solid #ccc;border-bottom:1px solid #ccc; padding:5px 15px; " |
允许您用已连接的USB配件直接进行枚举和交流
|- style=" vertical-align:top;"
| style=" border-right:1px solid #ccc;border-bottom:1px solid #ccc; padding:5px 15px; " |
UsbAccessory
| style="border-right:1px solid #ccc;border-bottom:1px solid #ccc; padding:5px 15px; " |
可以表示一个USB配件并且包含来连接识别信息的方法
|}
关于平台APIs和附加类库之间的用法差异
在分别使用谷歌APIs附加类库和平台APIs的时候,通常会有两种差异。
如果您正在使用附加类库,则肯定会通过下列方式来创建UsbManager对象:
1 |
UsbManager manager = UsbManager.getInstance(this); |
如果您不是用的附加类,则必须通过下列方式来创建UsbManager对象:
1 |
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); |
当您通过一个意图过滤器来过滤一个已经连接的配件,那么这个UsbAccessory对象就必须包含在传给您应用的这个意图中。如果您正在使用附加类库,您就必须通过下列方式来声明UsbAccessory对象:
UsbAccessory accessory = UsbManager.getAccessory(intent);
如果您不是用的附加类,则必须通过下列方式来声明UsbAccessory对象:
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
Android ManiFest 需求
下面的列表向您描述了在用USB配件APIs工作前需要在您应用中的manifest文件里面添加什么。下面的清单和资源文件例子将教您如何声明这些项:
* 因为并不是所有搭载Android系统的设备都保证支持USB配件APIs,包括一个元素来声明您的应用具有
android.hardware.usb.accessory这个特色。
* 如果你正在使用附加类库,添加com.android.future.usb.accessory。
* 如果您使用附加类库,那么您所设置的最低SDK版本是10级;如果您使用android.harware.usb这个类的话,您所设置最低版本的SDK就应该为12级。
* 如果您希望您的应用带有一个附加USB配件的通知,在您的主activity中为和元素指向一个额外的声明关于你希望探测到的配件的识别信息的XML资源文件。
在这个XML资源文件中,为您希望过滤的配件声明都有下面的属性:
:* 制造商
:* 模式
:* 版本
在元素指定的一样。这个XML资源文件的格式在下面的例子中给出。
清单和资源文件例子
下面的例子就为您展示了一个简单的manifest以及与之相关的资源文件:
1 |
<uses-sdk android:minSdkVersion="<version>" /> |
在这种情况之下,下面的资源文件保存在res/xml/accessory_filter.xml文件中,并且指定那些只有与其相关的模式,制造商和版本的配件能够被选择。这个配件把这些属性传递给搭载Android系统的设备:
<?xml version"utf-8"?>
用配件工作
当用户将USB配件连接到搭载Android系统的设备上面时,Android系统会判断您的应用是否适用于已连接的该配件。如果适用,您就可以根据您的喜好为该设备建立连接。要这么做,您的应用必须做下面这些动作:
您需要通过一个可以过滤配件附加事件的意图过滤器或者枚举已连接的配件来发现连接的配件来找到合适的接口。
尚未获得许可的用户在适用配件操作时需要验证权限。
通过在接入的端点进行读写数据的操作达到和配件交互的目的。
发现配件
您的应用可以通过两种方式来发现配件,一种是用一个意图过滤器在用户连接一个配件时对其进行通知,另一种则是通过枚举您已经连接的所有配件。如果您希望您的应用能够自动的探测到你想要的配件,请使用一个意图过滤器来做。但是,如果您希望得到一个已连接配件的列表或者您不希望过滤意图,枚举所有的配件会是一个更好的选择。
使用一个意图过滤器
为了让您的应用可以发现一个特定的USB配件,您可以为android.hardware.usb.action.USB_ACCESSORY_ATTACHED这个意图指定一个意图来进行过滤。伴随着这个意图过滤器,您需要指定一个资源文件来特别说明这个USB配件的属性,例如制造商,模式和版本。当用户连接到一个符合您配件过滤条件的配件时,
下面的例子告诉您该如何声明这个意图过滤器:
...
1 |
<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" |
下面的例子告诉您怎么样声明指定您希望连接的USB配件的相关资源文件:
<?xml version"utf-8"?>
在您的activity文件中,您可以从像这样的意图(有附加类的)中获取UsbAccessory来代表这个相关的配件:
UsbAccessory accessory = UsbManager.getAccessory(intent);
或者像这样(用平台APIs的):
UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
枚举所有配件
您可以使您的应用在运行时列举出所有能够被识别的配件。
通过getAccessoryList()方法来获得一个包含所有已连接USB配件的数组:
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbAccessory[] accessoryList = manager.getAcccessoryList();
* 注意:* 现在,只能一次连接一个USB配件操作,但是在以后的API中会支持多配件的操作的。
获得使用一个配件的权限
在您使用一个配件前,您的应用必须从用户那里获得权限。
* 注意:* 如果您的应用在连接配件时通过一个意图过滤器来发现它们,如果用户允许您的应用来处理这个意图,它将自动接收这个权限。如果用户不允许,那么您就必须在连接配件之前详细在您的应用中写明需要请求的权限。
在某些情况下很有必要明确权限的许可要求,例如当您的应用枚举出所有已经连接的配件并且您希望和其中的一个进行“交流”。您必须在和该配件“交流”前检查是否有连接该配件的权限。如果不是这样,您的应用将在用户拒绝您连接该配件的权限之后收到个运行错误。
为了确切地获得权限,首先需要创建个广播接收器。这个接收器在您调用requestPermission()这个方法时从您得到的广播中舰艇这个意图。通过调用requestPermission()这个方法为用户跳出一个是否连接配件的对话框。下面的例子告诉您如何创建一个广播接收器:
private static final String ACTION_USB_PERMISSION =
"com.android.example.USB_PERMISSION";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
1 |
public void onReceive(Context context, Intent intent) {
|
};
为了注册您的广播接收器,将其放在您activity中的onCreate()方法中去:
UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
private static final String ACTION_USB_PERMISSION =
"com.android.example.USB_PERMISSION";
...
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
当您需要展示征求用户同意连接这个配件的权限的对话框时,调用requestPermission()这个方法:
UsbAccessory accessory;
...
mUsbManager.requestPermission(accessory, mPermissionIntent);
当用户回应这个对话框时,你的广播接收器就会收到一个包含用一个boolean值来表示结果的EXTRA_PERMISSION_GRANTED字段的意图。在您连接配件之前检查这个字段的值是否为true。
和配件之间的“交流”
您可以通过使用UsbManager这个类和配件进行“交流”,通过这个类可以获得一个文件描述符,然后您可以利用这个描述符来设置输入和输出流来读取和写入数据。这些流用来代表输入和输出的批量端点。您最好另起一个线程来让您的设备和配件进行“交流”,因为这样您就可以不需要将主线程锁起来了。下面的例子告诉您该如何和一个配件进行“交流”:
UsbAccessory mAccessory;
ParcelFileDescriptor mFileDescriptor;
FileInputStream mInputStream;
FileOutputStream mOutputStream;
...
private void openAccessory() {
Log.d(TAG, "openAccessory: " + accessory);
mFileDescriptor = mUsbManager.openAccessory(mAccessory);
if (mFileDescriptor != null) {
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInputStream = new FileInputStream(fd);
mOutputStream = new FileOutputStream(fd);
Thread thread = new Thread(null, this, "AccessoryThread");
thread.start();
}
}
在这个线程的run()方法中,您可以通过FileInputStream或者FileOutputStream对象来对配件进行读取和写出数据操作。当您通过FileInputStream对象读取配件中的数据时,请确保您所使用的缓存能够存储下USB数据包数据。Android配件协议支持数据包支持高达16384字节的数据包缓存区,所以您可以选择一直让您的缓存区是这个简单的大小。
* 注意:* 在一个比较低的水平下,64字节的数据包是全速配件以及512字节的数据包是高速配件。Android配件协议将这两种速度捆绑成一个简单的逻辑数据包。
想要知道更多如何使用Android中多线程的信息,请参见进程和线程。
中止和配件的“交流”
当您在完成和配件的“交流”之后,又或者该配件被移除了,通过调用close()方法来关闭你已经打开的文件描述符。为了监听分离这样的事件,您需要创建一个如下的广播接收器:
BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
1 |
if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
|
};
在您的应用中创建这个广播接收器,不是在manifest文件中,允许您的应用只能在它运行的时候处理这样的配件分离事件。这样的话,配件分离这个事件就只向正在运行的应用广播,而不是向所有的应用进行广播。
Android USB配件模式的更多相关文章
- android usb Host模式下与usb Hid 设备的通信
做android 与USB HID设备的通信有段时间了,总结一下遇到的问题和解决方法: 1,第一次遇到的问题:android 版本低不支持usb hid, 被要求做相关项目的时候,就从mUsbMana ...
- Android 5.0 版本 USB 调试模式打开方法
Android 4.2 版本 USB 调试模式打开方法 1. 进入“设置”页面,点击“关于平板电脑”.见下图红色方框. 2. 疯狂点击“版本号”,见下图红色方框,直到出现“您现在处于开发者模式!” ...
- USB Accessory 模式
USB Accessory 模式USB附件模式允许用户连接专为Android设备设计的USB主机硬件.配件必须遵守Android配件开发套件文档中概述的Android附件协议.这使得无法充当USB主机 ...
- Android USB Host与HID通讯 (二)
不好意思,从上一篇到现在确实比较忙,中间又外出了一段时间,虽然也上LOFTER,或者看到一些朋友QQ上加我,给我发信息询问,有些看到了有些可能没看到,偶尔回复了一两个,也不咋的详细,在此我想说,一方面 ...
- 翻译Android USB HOST API
翻译Android USB HOST API 源代码地址:http://developer.android.com/guide/topics/connectivity/usb/host.html 译者 ...
- [译] iOS 11.4.1 Beta:全新的USB限制模式
(Source/原文链接 https://blog.elcomsoft.com/2018/06/ios-11-4-1-beta-usb-restricted-mode-has-arrived/) 作者 ...
- 『翻译』Android USB Host
USB Host When your Android-powered device is in USB host mode, it acts as the USB host, powers the b ...
- Android USB Host框架
Android 下的usb框架及功能点:https://blog.csdn.net/tianruxishui/article/details/379029591.Android framework中* ...
- Android USB转串口通信开发基本流程
好久没有写文章了,年前公司新开了一个项目,是和usb转串口通信相关的,需求是用安卓平板通过usb转接后与好几个外设进行通信.一直忙到近期,才慢慢闲下来,趁着这个周末不忙.记录下usb转串口通信开发的基 ...
随机推荐
- MongoDB副本集配置系列三:副本集的认证方式
1:副本集配置参考这篇博客: http://www.cnblogs.com/xiaoit/p/4478951.html 2:副本集的认证 假设有两台机器已经配置好了副本集(副本集罪一般最少3台机器,这 ...
- ReactNative踩坑日志——如何实现删除scrollview中的视图
在reactNative中,页面是根据state值的变化来重新渲染的.因此,传统的前端开发中通过 id 来移除一个页面元素的做法在这里不适用. 一般,我们是通过遍历数组或map来渲染出scrollvi ...
- Web服务器讲解与JavaWeb应用部署(本机,以Tomcat为例)
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6042290.html 在讨论Web系统发布之前,我们先来辨析两个概念:服务器.Web服务器. 通常,我们说的服 ...
- 粒子滤波跟踪移动机器人(MATLAB Robotics System Toolbox)
MathWorks从MATLAB 2015a开始推出与ROS集成的Robotics System Toolbox(机器人系统工具箱),它为自主移动机器人的研发提供现成的算法和硬件接口. 粒子滤波基本流 ...
- django之创建站点之基本流程
创建工程: 1.在D盘下创建一个文件夹名为djangoweb,切换到文件夹所在目录 C:\Administrator>d: D:\>cd d:\djangoweb 2.创建工程(成功没有提 ...
- 转 安装PHP出现make: *** [sapi/cli/php] Error 1 解决办法
ext/iconv/.libs/iconv.o: In function `php_iconv_stream_filter_ctor':/home/king/php-5.2.13/ext/iconv/ ...
- 【转】UIAutomator源码分析之启动和运行
我们可以看到UiAutomator其实就是使用了UiAutomation这个新框架,通过调用AccessibilitService APIs来获取窗口界面控件信息已经注入用户行为事件,那么今天开始我们 ...
- RS:关于协同过滤,矩阵分解,LFM隐语义模型三者的区别
项亮老师在其所著的<推荐系统实战>中写道: 第2章 利用用户行为数据 2.2.2 用户活跃度和物品流行度的关系 [仅仅基于用户行为数据设计的推荐算法一般称为协同过滤算法.学术界对协同过滤算 ...
- Vue.js——60分钟快速入门 开发· webpack 中文文档
转载于:http://www.cnblogs.com/keepfool/p/5619070.html http://www.css88.com/doc/webpack2/guides/get-star ...
- TCP连接建立与释放
tcp建立连接 tcp连接的建立需要经历”三次握手“的过程.过程如下 client发送SYN包(值为j)以及SEQ包到server端,此时client进入SYN_SEND状态.此为第一次握手. ser ...