江门市华企立方科技有限公司,外贸seo博客,网站点,官方网站哪家做的最好USB Accessory#xff08;配件模式#xff09;
USB 配件模式允许用户连接专为 Android 设备设计的 USB 主机硬件。配件必须遵守 Android Accessory Development Kit 文档中列出的 Android 配件协议。 这使得 Android 设备无法充当 USB 主机时仍然可以与 USB 硬件交互。 当 A…USB Accessory配件模式
USB 配件模式允许用户连接专为 Android 设备设计的 USB 主机硬件。配件必须遵守 Android Accessory Development Kit 文档中列出的 Android 配件协议。 这使得 Android 设备无法充当 USB 主机时仍然可以与 USB 硬件交互。 当 Android 设备处于 USB 配件模式时所连接的 Android USB 配件充当主机为 USB 总线供电并枚举所连接的设备。 Android 3.1API 级别12支持 USB 配件模式该功能也被以附加组件库的方式回溯到 Android 2.3.4API 级别10以支持更广泛的设备。前提是厂商必须在系统镜像中添加附加组件库。
选择正确的 USB Accessory API 函数
尽管 USB accessory API 函数在 Android 3.1 引入到平台通过使用 Google APIs 附加库的方式用在 Android 2.3.4 上。由于这些 APIs 使用外部库的方式回溯有两个包可以导入来支持 USB 配件模式。根据你要支持的安卓设备您可能要使用一个库而不是另一个
com.android.future.usb: 为了在 Android 2.3.4 中支持 USB accessory 模式Google APIs add-on library 包括回溯的 USB accessory API它们包含在此命名空间中。 Android 3.1 还支持在此命名空间中导入和调用类以支持使用附加库编写的应用程序。 这个附加库是围绕 android.hardware.usb accessory API 的简版 wrapper不支持USB主机模式。 如果您想支持最广泛的支持 USB accessory 模式的设备请使用附加库并导入此软件包。 重要的是要注意并非所有的 Android 2.3.4 设备都需要支持 USB 配件功能。 每个单独的设备制造商决定是否支持此功能这就是为什么必须在 manifest 文件中声明它。 android.hardware.usb: 此命名空间包含在 Android 3.1 中支持 USB accessory 模式的类。 该软件包作为 framework API 的一部分Android 3.1 支持 USB accessory 模式而不需要附加库。 如果您只关心具有 USB accessory 模式硬件支持的 Android 3.1 或更新版本您可以在清单文件中声明使用此软件包。
安装 Google APIs 附加库
如果要安装该附加库可以通过使用 SDK Manager 安装 Google API Android API 10 软件包。有关安装附加库的更多信息请参阅 Installing the Google APIs Add-on。API 概述
由于附加库是 framework API 的 wrapper因此支持 USB accessory 功能的类很相似。 即使您正在使用附加库也可以使用 android.hardware.usb 的参考文档。
Note但是您应该注意的附加库和 framework API 之间存在较小的用法差异。 下表描述支持 USB accessory API 的类 Class Description UsbManager 允许枚举以及与已连接 USB 配件通讯 UsbAccessory 表示USB 配件包含访问其标识信息的方法 附加库和平台 APIs 的使用差别 在使用 Google APIs 和平台 APIs 之间有两处使用区别。 如果正在使用附加库必须以下列方式获取 UsbManager
UsbManager manager UsbManager.getInstance(this); 如果没在使用附加库必须以下列方式获取 UsbManager UsbManager manager (UsbManager) getSystemService(Context.USB_SERVICE); 当您使用 intent filter 过滤连接的配件时UsbAccessory 对象包含在传递给应用程序的 intent 内。 如果正在使用附加库则必须以下列方式获取 UsbAccessory 对象 UsbAccessory accessory UsbManager.getAccessory(intent); 如果没在使用附加库必须以下列方式获取 UsbAccessory UsbAccessory accessory (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); 安卓 Manifest 要求 以下列表描述了在使用 USB accessory API 之前需要添加到应用程序的 manifest 文件中的内容。manifest and resource file examples 展示了如何声明这些项目 1. 因为并非所有 Android 设备被授权支持 USB accessory API因此包含一个 uses-feature 元素声明您的应用程序使用 android.hardware.usb.accessory 功能。 2. 如果您正在使用附加库请添加指定 com.android.future.usb.accessory 的 uses-library 元素。 3. 如果您正在使用附加库请将应用程序的最小 SDK 设置为 API Level 10如果使用的是android.hardware.usb 包则将其设置为12。 4. 如果您希望应用程序在 USB 配件连接时收到通知请在主要活动中为 android.hardware.usb.action.USB_ACCESSORY_ATTACHED 意图指定 intent-filter 和 meta-data 元素对。meta-data 元素指向一个外部XML资源文件它声明了您想检测的配件的标识信息。 在XML资源文件中为要过滤的配件声明 usb-accessory 元素。每个 usb-accessory 可以具有以下属性 manufacturer model version 将资源文件保存在 res/xml/ 目录中。资源文件名不含 .xml 扩展名必须与您在 meta-data 元素中指定的文件名相同。 XML资源文件的格式也展示在下面的 example 中。Manifest 和 资源文件示例 以下示例展示了一个 manifest 样例及相应的资源文件 manifest ...uses-feature android:nameandroid.hardware.usb.accessory /uses-sdk android:minSdkVersionversion /...applicationuses-library android:namecom.android.future.usb.accessory /activity ......intent-filteraction android:nameandroid.hardware.usb.action.USB_ACCESSORY_ATTACHED //intent-filtermeta-data android:nameandroid.hardware.usb.action.USB_ACCESSORY_ATTACHEDandroid:resourcexml/accessory_filter //activity/application
/manifest 在这个案例中下面的资源文件应该保存在 res/xml/accessory_filter.xml 中并且指定具有相关 model、manufacturer、version 的配件应该被过滤。配件将这些属性发送给 Android 设备
?xml version1.0 encodingutf-8?resourcesusb-accessory modelDemoKit manufacturerGoogle version1.0/
/resources 使用配件 当用户将 USB 配件连接到 Android 设备时Android 系统可以决定您的应用程序是否对连接的配件感兴趣。 如果是这样如果需要您可以设置与附件的通信。如果是这样您可以根据需要建立与设备的通信。为此您的应用程序必须 1. 通过使用 intent filter 过滤配件连接事件来发现配件或通过枚举已连接的配件找到正确的配件。 2. 请求用户连接 USB 配件的权限如果尚未获得。 3. 在正确的接口端点上读写数据与 USB 配件进行通信。 发现配件 应用程序可以通过使用 intent filter 在用户连接配件时收到通知或通过枚举已连接的 USB 配件来发现 USB 配件。如果您希望能够让应用程序自动检测到所需的配件则使用 intent filter 非常有用。 如果要获取所有连接的配件列表或者您的应用程序没有为 intent 进行过滤则枚举已连接的 USB 配件的方法非常有用。 使用 intent filter意图过滤器 要使您的应用程序发现一个特定的 USB peijia可以指定一个 intent filter 来过滤 android.hardware.usb.action.USB_ACCESSORY_ATTACHED intent。 除了此 intent filter您还需要指定一个资源文件该资源文件指定 USB 配件的属性如 manufacturer、model 和 version。 当用户连接与 accessory filter 匹配的配件时 以下示例展示如何声明 intent filter activity ......intent-filteraction android:nameandroid.hardware.usb.action.USB_ACCESSORY_ATTACHED //intent-filtermeta-data android:nameandroid.hardware.usb.action.USB_ACCESSORY_ATTACHEDandroid:resourcexml/accessory_filter /
/activity 以下示例展示如何声明相应资源文件其指定了感兴趣的 USB 配件 ?xml version1.0 encodingutf-8?resourcesusb-accessory manufacturerGoogle, Inc. modelDemoKit version1.0 /
/resources 在你的活动中你可以像这样从 intent 中获取表示连接附件的 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(); Note同一时间只可以支持一个已连接配件。 获取与配件进行通信的权限 在与 USB 配件进行通信之前应用程序必须获得用户的许可。 Note如果应用程序 uses an intent filter 来发现连接时的 USB 配件则如果用户允许您的应用程序处理 intent则它将自动接收权限。如果没有您必须在连接到配件之前在应用程序中明确请求权限。 在某些情况下显式请求权限可能是必需的例如当您的应用程序枚举到已连接的 USB 配件然后要与其进行通信时。在尝试与之通信之前您必须检查访问配件的权限。如果没有用户拒绝访问配件的权限时您将收到 runtime 错误。 要明确获得许可首先创建一个广播接收器。该接收器侦听当您调用 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);}}}}
}; 要注册广播接收器在活动的 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 的 intent这是表示答案的布尔值。 在连接配件之前请检查这个额外值是否为 true。 与配件通信 您可以使用 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();}
} 在线程的 run() 方法中可以使用 FileInputStream 或 FileOutputStream 对象来读写配件。 使用 FileOutputStream 对象从配件读取数据时请确保使用的缓冲区足够大以存储 USB 数据包数据。 Android 配件协议支持高达16384字节的数据包缓冲区因此为了简单起见您可以选择始终声明缓冲区为此大小。 Note注意在较低级别USB 全速配件的数据包为64字节USB 高速配件为512字节。 为了简单起见Android 配件协议将两个速度的数据包捆绑在一起成为一个逻辑数据包。 有关在 Android 中使用线程的更多信息请参阅 Processes and Threads。 终止与配件通信 当你与配件通信完成或者配件拔出时调用 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}}}
}; 在应用程序中而不是 manifest 中创建广播接收器允许应用在运行时只处理拔除事件。通过这种方式广播事件只会发送到当前正在运行的应用程序而不是广播到所有应用。 原文链接https://developer.android.com/guide/topics/connectivity/usb/accessory.html