USB Accessory 模式

USB Accessory 模式
USB附件模式允许用户连接专为Android设备设计的USB主机硬件。配件必须遵守Android配件开发套件文档中概述的Android附件协议。这使得无法充当USB主机的Android电源设备仍然可以与USB硬件交互。当Android设备处于USB附件模式时,所附的Android USB附件充当主机,为USB总线供电,并列举连接的设备。 Android 3.1(API级别12)支持USB附件模式,并且该功能也被返回到Android 2.3.4(API级别10),以支持更广泛的设备

a. 选择正确的USB附件API
虽然USB附件API已经在Android 3.1平台上引入,但Android 2.3.4中也可以使用Google API附加库。因为这些API是使用外部库进行反向输入的,所以有两个包可以导入以支持USB附件模式。根据您要支持的Android驱动的设备,您可能需要使用其他设备:
com.android.future.usb:要在Android 2.3.4中支持USB附件模式,Google API附加库包括后端的USB附件API,它们包含在此命名空间中。 Android 3.1还支持在此命名空间中导入和调用类,以支持使用附加库编写的应用程序。这个附加库是围绕android.hardware.usb附件API的薄包装,不支持USB主机模式。如果要支持最广泛的支持USB附件模式的设备,请使用附加库并导入此软件包。重要的是要注意,并不是所有的Android 2.3.4设备都需要支持USB附件功能。每个设备制造商决定是否支持此功能,这就是为什么必须在清单文件中声明它。
android.hardware.usb:这个命名空间包含在Android 3.1中支持USB附件模式的类。该软件包作为框架API的一部分,所以Android 3.1支持USB附件模式而不使用附加库。如果您只关心具有USB附件模式硬件支持的Android 3.1或更新的设备,您可以在清单文件中声明,请使用此软件包。
b. API概述

UsbManager 允许您枚举和连接所连接的USB附件。
UsbAccessory 表示USB附件,包含访问其识别信息的方法。
如果您正在使用附加库,则必须以下列方式获取UsbManager对象:

UsbManager manager = UsbManager.getInstance(this);
1
如果您正在使用附加库,则必须以下列方式获取UsbManager对象:

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
1
如果您不使用附加库,则必须以下列方式获取UsbAccessory对象:

UsbAccessory accessory = UsbManager.getAccessory(intent);
1
如果您不使用附加库,则必须以以下方式获取UsbAccessory对象:

UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
1
c. Android Manifest 要求
以下列表描述了在使用USB辅助API之前需要添加到应用程序的清单文件中。清单和资源文件示例显示如何声明这些项目:

因为并非所有Android设备都能保证支持USB附件API,还包括一个元素,声明您的应用程序使用android.hardware.usb.accessory功能。
如果您正在使用附加库,请添加指定库的com.android.future.usb.accessory的元素。
如果您正在使用附加库,请将应用程序的最小SDK设置为API Level 10,如果使用的是android.hardware.usb包,则将其设置为12。
如果希望您的应用程序被通知附加的USB附件,请在主要活动中为android.hardware.usb.action.USB_ACCESSORY_ATTACHED意图指定和元素对。 元素指向一个外部XML资源文件,它声明要检测的附件的信息。
在XML资源文件中,为要过滤的附件声明元素。每个可以具有以下属性:

manufacturer
model
version
1
2
3
将资源文件保存在res / xml /目录中。资源文件名(不含.xml扩展名)必须与您在元素中指定的文件名相同。 XML资源文件的格式也在下面的示例中显示

Manifest 和 resource 文件示例

<manifest>
<uses-feature android:name="android.hardware.usb.accessory" />

<uses-sdk android:minSdkVersion="<version>" />
...
<application>
<uses-library android:name="com.android.future.usb.accessory" />
<activity ...>
...
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>

<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
</activity>
</application>
</manifest>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
在这种情况下,应将以下资源文件保存在res / xml / accessory_filter.xml中,并指定具有相应型号,制造商和版本的任何附件应被过滤。配件将这些属性发送给Android设备:

<?xml version="1.0" encoding="utf-8"?>
< resources>
< usb-accessory model="DemoKit" manufacturer="Google" version="1.0"/>
< /resources>
1
2
3
4
Working with Accessory
当用户将USB附件连接到Android设备时,Android系统可以确定您的应用程序是否对连接的附件感兴趣。如果是这样,如果需要,您可以设置与附件的通信。为此,您的应用程序必须:

1、通过使用过滤附件事件的意图过滤器或枚举连接的附件并找到适当的附件来发现连接的附件。
2、要求用户与附件通信,如果尚未获得。
3、通过在适当的接口端点上读取和写入数据来与附件通信。

Discovering an accessory
您的应用程序可以通过使用意图过滤器来发现附件,以便在用户连接附件或枚举已连接的附件时收到通知。如果希望能够让应用程序自动检测到所需的附件,则使用意图过滤器很有用。如果您想获得所有连接的配件的列表,或者您的应用程序没有为意图过滤,枚举连接的附件是有用的。

Using an intent filter
要使您的应用程序发现一个特定的USB附件,您可以指定一个intent过滤器来过滤android.hardware.usb.action.USB_ACCESSORY_ATTACHEDintent。除了该intent过滤器之外,还需要指定一个资源文件,该文件指定USB配件的属性,如制造商,型号和版本。当用户连接与您的附件过滤器相匹配的附件时,

以下示例显示如何声明intent过滤器:

< activity ...>
...
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>

<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
< /activity>
1
2
3
4
5
6
7
8
9
以下示例显示如何声明指定您感兴趣的USB附件的相应资源文件:

<?xml version="1.0" encoding="utf-8"?>

<resources>
<usb-accessory manufacturer="Google, Inc." model="DemoKit" version="1.0" />
</resources>
1
2
3
4
5
在您的活动中,您可以从这样的intent(使用附加库)获取代表附件的UsbAccessory:

UsbAccessory accessory = UsbManager.getAccessory(intent);
或者像这样(使用平台API):

UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
枚举 accessories

您的应用程序可以枚举在应用程序运行时识别自己的配件。
使用getAccessoryList()方法获取所有连接的USB附件的阵列:

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbAccessory[] accessoryList = manager.getAcccessoryList();
获取与附件通信的权限

在与USB配件进行通信之前,您的应用必须得到用户的许可。

注意:如果您的应用程序使用意图过滤器在附件中发现附件,则如果用户允许您的应用程序处理意图,则它会自动接收权限。如果没有,您必须在连接到附件之前在应用程序中明确请求许可。

在某些情况下,明确请求许可可能是必需的,例如当您的应用程序枚举已连接的配件,然后要与其进行通信时。在尝试与之通信之前,您必须检查访问附件的权限。如果没有,如果用户拒绝访问附件的权限,您将收到运行时错误。

要明确获得许可,首先创建广播接收器。该接收器侦听当您调用requestPermission()时获得广播的意图。对requestPermission()的调用向用户显示一个对话框,要求连接到附件的权限。以下示例代码显示了如何创建广播接收器:

private static final String ACTION_USB_PERMISSION =
“com.android.example.USB_PERMISSION”;
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbAccessory accessory =(UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);

if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(accessory != null){
//call method to set up accessory communication
}
}
else {
Log.d(TAG, "permission denied for accessory " + accessory);
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
};
要注册广播接收器,请将其放在您的活动中的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);
当用户回复对话框时,您的广播接收方收到包含EXTRA_PERMISSION_GRANTED extra的意图,这是一个表示答案的布尔值。在连接附件之前,请检查这个额外的值是否为true。

与 Accessory 通讯
您可以通过使用UsbManager与附件通信,以获取一个文件描述符,您可以设置输入和输出流来读写数据到描述符。流代表配件的输入和输出批量端点。您应该在另一个线程中设置设备和附件之间的通信,因此您不会锁定主UI线程。以下示例显示如何打开附件进行通信:

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();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
在线程的run()方法中,您可以使用FileInputStream或FileOutputStream对象来读写附件。使用FileInputStream对象从附件读取数据时,请确保您使用的缓冲区足够大以存储USB数据包数据。 Android附件协议支持高达16384字节的数据包缓冲区,为了简单起见您可以选择始终声明缓冲区:

注意:在较低的级别,USB全速附件的数据包为64字节,USB高速附件为512字节。为了简单起见,Android附件协议将两个速度的数据包捆绑在一起成为一个逻辑数据包。

有关在Android中使用线程的更多信息,请参阅进程和线程。

终止与附件的通信

当您完成与附件的通信或附件脱离后,通过调用close()关闭您打开的文件描述符。要收听分离的事件,请创建如下广播接收器:

BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();

if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null) {
// call your method that cleans up and closes communication with the accessory
}
}
}
1
2
3
4
5
6
7
};
在应用程序中创建广播接收者,而不是清单,允许您的应用程序在运行时仅处理分离的事件。这样,分离的事件只会发送到当前运行的应用程序,而不是广播到所有的应用程序

原文地址:https://www.cnblogs.com/zxc2man/p/11840766.html

时间: 2024-10-10 16:52:09

USB Accessory 模式的相关文章

android里面的USB功能-----Accessory模式

USB Accessory 原文链接地址  http://developer.android.com/intl/zh-cn/guide/topics/connectivity/usb/accessory.html#manifest USB附件模式允许用户连接 USB主机硬件专门为android设备. 配件必须遵循 Android附属协议中列出 Android配件开发工具包文档. 这允许android设备仍不能作为USB主机与USB接口进行交互 硬件. 当一个Android设备在USB附件模式中,

红米note怎么打开USB调试模式

红米note到货后,打开USB调试模式是一些新手很棘手的问题,所以要手机助手成功识别红米note,你必须打开红米note的USB调试模式.在安卓4.2版本中,系统的USB调试模式不是非常简单地被打开的.红米note采用的就是基于安卓4.2及以上的MIUI操作系统. 方法/步骤 1.在红米note界面中,您会看到桌面中的"设置"图标,点击进入红米note设置界面. 2.在设置界面中点击"全部设置",然后再界面最底端点击"关于手机"选项. 3.在&q

Linux下adb驱动问题Linux下使用手机USB调试模式连接ADB进行Android程序的调试

Linux 下adb 驱动问题 Linux下使用手机USB调试模式连接ADB进行Android程序的调试,配置驱动没有Windows来的直观. 具体步骤首先确认手机连接上电脑,lsusb查看下设备记录. [email protected]:~$ lsusb Bus 007 Device 009: ID 18d1:4e12 Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 006 Device 001: ID 1d

Android 5.0 版本 USB 调试模式打开方法

Android 4.2 版本 USB 调试模式打开方法 1. 进入“设置”页面,点击“关于平板电脑”.见下图红色方框.   2. 疯狂点击“版本号”,见下图红色方框,直到出现“您现在处于开发者模式!”. 8 3. 出现“您现在处于开发者模式!”.见下图红色方框. 4. 退回到“设置”页面,这时在“关于平板电脑”上面多了一个“开发者选项”,点击进入.见下图红色方框   5. 勾选“USB调试”.见下图红色方框.注意:右上角的开关要保持“打开”状态 11 6. 点击“确定”,允许USB调试.见下图红

(简单)华为荣耀4A SCL-TL00的usb调试模式在哪里打开的方法

当我们使用Pc通过数据线连接上安卓手机的时候,如果手机没有开启USB开发者调试模式,Pc则没法成功检测到我们的手机,在一些情况下,我们使用的一些功能较好的应用软件比如之前我们使用的一个应用软件引号精灵,老版本就需要开启USB开发者调试模式下使用,现当新版本不需要了,这时候我们需要找解决方法将手机的USB开发者调试模式开启,这里我们介绍华为荣耀4A SCL-TL00如何开启USB开发者调试模式的步骤. 首先,在华为荣耀4A SCL-TL00应用程序界面点击设置ICON,进入华为荣耀4A SCL-T

(简单)华为P9plus VIE-AL00的usb调试模式在哪里开启的经验

每次我们使用pc接通安卓手机的时候,如果手机没有开启Usb调试模式,pc则没能成功检测到我们的手机,有时,我们使用的一些功能比较强的的app比如之前我们使用的一个app引号精灵,老版本就需要打开Usb调试模式下使用,现每次新版本不需要了,此情况我们需要找解决方法将手机的Usb调试模式打开,本文我们叙述华为P9plus VIE-AL00如何开启Usb调试模式的方法.接着,在华为P9plus VIE-AL00应用程序界面打开"设置"图标,进入华为P9plus VIE-AL00系统"

(完美)华为畅玩7A AUM-AL00的Usb调试模式在哪里打开的步骤

当我们使用PC链接安卓手机的时候,如果手机没有开启usb调试模式,PC则不能够成功检测到我们的手机,有时候我们使用的一些功能强大的app好比以前我们使用的一个app引号精灵,老版本就需要打开usb调试模式下使用,现当新版本不需要了,因此我们需要找方法将手机的usb调试模式打开,以下内容我们记录一下华为畅玩7A AUM-AL00如何开启usb调试模式的步骤.接着,在华为畅玩7A AUM-AL00应用程序界面打开<设置>ICON,进入华为畅玩7A AUM-AL00系统<设置>界面.第二

(简单)华为Nova3 PAR-AL00的USB调试模式在哪里开启的步骤

当我们使用pc链接安卓手机的时候,如果手机没有开启Usb调试模式,pc则不能够成功检测到我们的手机,有时候,我们使用的一些功能比较强的的应用如之前我们使用的一个应用引号精灵,老版本就需要打开Usb调试模式下使用,现当新版本不需要了,这个时候我们需要找处理方法将手机的Usb调试模式打开,如下内容我们叙述华为Nova3 PAR-AL00如何开启Usb调试模式的流程. 首先在华为Nova3 PAR-AL00应用程序界面点击设置图标,进入华为Nova3 PAR-AL00系统设置界面. 然后点击设置界面上

(最简单)MIUI7系统的usb调试模式在哪里打开的流程

在我们使用安卓手机链接Pc的时候,或者使用的有些软件比如我们团队营销小组在使用的软件引号精灵,以前老版本就需要开启Usb开发者调试模式下使用,不过,现在新版本不需要了,如果手机没有开启Usb开发者调试模式,Pc则不能够成功检测到我们的手机,部分软件也不能够正常使用,这个时候我们需要想办法将手机的Usb开发者调试模式打开,以下内容我们记录一下MIUI7系统如何开启Usb开发者调试模式的方法.首先,在MIUI7系统应用程序界面启动设置ICON,进入MIUI7系统系统设置界面.第二步点击设置界面上的我