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

来源:互联网 发布:php redis 扩展 编辑:程序博客网 时间:2024/04/28 18:46

USB Host


在你的android设备上USB主机模式,它作为USB主机,权力的公共汽车, 并列举了USB设备连接。 USB主机模式支持Android 3.1和更高版本。

API概述


在您开始之前,重要的是要理解你所需要的类。 的 下表描述了USB主机的api android.hardware.usb 包中。

表1。 USB主机api

描述UsbManager允许你列举和与连接USB设备通信。UsbDevice代表一个连接USB设备和包含的方法来访问它的识别 信息、接口和端点。UsbInterface代表一个USB设备的接口,它定义了一组的功能 设备。 一个设备可以有一个或多个接口的通信。UsbEndpoint代表一个接口端点,该接口的通信通道。 一个 接口可以有一个或多个端点,通常有输入和输出端点 双向通信的设备。UsbDeviceConnection代表一个连接到设备,数据传输的端点。 这个类 允许你来回同步或异步发送数据。UsbRequest代表了一个异步请求与设备通过通信 UsbDeviceConnection UsbConstants对应于定义定义了USB的常量在linux / USB / ch9。 h(Linux 内核。

在大多数情况下,您需要使用所有这些类( UsbRequest 只是如果你需要做异步通信) 当与USB设备通信。 一般来说,你获得一个 UsbManager 来检索所需的 UsbDevice 。 当你的设备,你需要找到合适的 UsbInterface UsbEndpoint 的 接口通信。 一旦你获得正确的端点,打开一个 UsbDeviceConnection 与USB设备进行通信。

Android清单要求


下面的列表描述了您需要添加到您的应用程序的清单文件 使用USB主机api:

  • 因为不是所有的android设备保证支持USB主机api, 包括一个 < uses-feature > 您的应用程序使用的元素声明 的 android.hardware.usb.host 特性。
  • 设置最低SDK应用程序的API级别12或更高。 USB主机api 早些时候出现在API级别。
  • 如果你想让你的应用程序连接USB设备的通知,指定一个 <意图过滤器> 和 <元数据> 元素对的android.hardware.usb.action.USB_DEVICE_ATTACHED 你的主要活动的意图。 的 <元数据> 元素指向外部声明的XML资源文件 确定要检测的设备信息。

    在XML资源文件中,申报的东西 < usb设备> USB的元素 你想过滤设备。 下面的列表描述的属性 < usb设备>。 一般来说,使用供应商和产品ID如果你想过滤器 为一个特定的设备和使用类、子类和协议如果你想过滤为一组 USB设备,如大容量存储设备或数码相机。 您可以指定或没有 所有这些属性。 没有匹配的属性指定每一个USB设备,所以只有这样做 如果您的应用程序要求:

    • 卖主身份证
    • 产品id
    • 子类
    • 协议 (设备或接口)

    节省的资源文件 res / xml / 目录中。 资源文件名称 (没有。 xml扩展)必须与你指定的相同 <元数据> 元素。 格式的XML资源文件 例子 在下面。

清单和资源文件的例子

下面的示例显示了一个示例清单和相应的资源文件:

<manifest ...>    <uses-feature android:name="android.hardware.usb.host" />    <uses-sdk android:minSdkVersion="12" />    ...    <application>        <activity ...>            ...            <intent-filter>                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />            </intent-filter>            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"                android:resource="@xml/device_filter" />        </activity>    </application></manifest>

在这种情况下,应该保存在下面的资源文件 res / xml / device_filter.xml 与指定的指定,任何USB设备 属性应该过滤:

<?xml version="1.0" encoding="utf-8"?><resources>    <usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" /></resources>

处理设备


当用户连接USB设备的Android设备上,Android系统可以确定 您的应用程序是否感兴趣的连接设备。 如果是这样,您可以设置 与设备如果需要沟通。 要做到这一点,您的应用程序有:

  1. 发现连接USB设备通过使用一个意图过滤器时通知用户 连接USB设备或通过列举USB设备已经连接。
  2. 要求用户允许连接到USB设备,如果不是已经获得。
  3. 与读写数据的USB设备在适当的接口 端点。

发现一个设备

您的应用程序可以发现USB设备通过使用一个意图过滤器时收到通知 用户连接设备或通过列举USB设备已经连接。 使用一个 意图过滤器是非常有用的,如果你想应用程序能够自动检测 所需的设备。 列举连接USB设备是有用的,如果你想要所有的列表 连接设备或如果你的应用程序没有过滤的目的。

使用一个意图过滤器

您的应用程序发现特定的USB设备,您可以指定一个意图过滤器 过滤器的android.hardware.usb.action.USB_DEVICE_ATTACHED 意图。 随着 此意图过滤器,您需要指定一个资源文件,指定属性的USB 设备,如产品和供应商ID。当用户连接的设备匹配你的设备 滤波器,系统给他们提供了一个对话框,询问如果他们想开始您的应用程序。 如果用户接受,您的应用程序自动权限访问设备,直到 设备断开连接。

下面的例子显示了如何声明意图过滤器:

<activity ...>...    <intent-filter>        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />    </intent-filter>    <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"        android:resource="@xml/device_filter" /></activity>

下面的例子展示了如何声明指定相应的资源文件 你感兴趣的USB设备:

<?xml version="1.0" encoding="utf-8"?><resources>    <usb-device vendor-id="1234" product-id="5678" /></resources>

在你的活动,你可以获得 UsbDevice 代表 附加设备的意图是这样的:

UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

列举设备

如果您的应用程序感兴趣的检查所有的USB设备当前连接 应用程序运行时,它可以枚举设备在公共汽车上。 使用getDeviceList() 方法来获取一个散列映射 连接的USB设备。 哈希映射键控的USB设备的名字,如果你想 从地图上获取一个设备。

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);...  HashMap<String, UsbDevice> deviceList = manager.getDeviceList();UsbDevice device = deviceList.get("deviceName");

如果需要,你也可以获得散列映射的迭代器和处理每个设备 一:

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);...HashMap<String, UsbDevice> deviceList = manager.getDeviceList();Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();while(deviceIterator.hasNext()){    UsbDevice device = deviceIterator.next();    //your code}

获得许可与设备进行通信

在与USB设备之前,应用程序必须得到你的许可 用户。

注意: 如果您的应用程序 使用一个 意图过滤器 发现他们连接USB设备,它可以自动接收 如果用户许可允许您的应用程序处理的目的。 如果没有,你必须请求 允许显式地在您的应用程序连接到设备。

明确要求许可可能是必要的在某些情况下,例如当你 应用列举了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) {                UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {                    if(device != null){                      //call method to set up device communication                   }                }                 else {                    Log.d(TAG, "permission denied for device " + device);                }            }        }    }};

注册广播接收器,添加你 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() 方法:

UsbDevice device;...mUsbManager.requestPermission(device, mPermissionIntent);

当用户回复的对话框,你的广播接收器接收包含意图 EXTRA_PERMISSION_GRANTED 额外的,这是一个布尔值 代表回答。 之前检查这个额外的价值真正的连接 设备。

与设备通信

沟通与USB设备可以是同步或异步的。 在这两种情况下,你 应该创建一个新线程来执行所有数据传输,所以你不阻止 UI线程。 正确设置通信设备,你需要获得适当的 UsbInterface 和 UsbEndpoint 的 设备你想交流和发送在这个端点的请求 UsbDeviceConnection 。 一般来说,您的代码应该:

  • 检查一个 UsbDevice 对象的属性,如产品ID、 供应商ID,或者设备类找出你是否想与交流 设备。
  • 当你确定你想与设备沟通,找到合适的 UsbInterface 您想使用与交流 适当的 UsbEndpoint 的接口。 接口可以有一个 或多个端点,通常会有一个双向的输入和输出端点 沟通。
  • 当你找到正确的端点,打开一个 UsbDeviceConnection 端点。
  • 提供你想要的数据传输的端点 bulkTransfer() 或 controlTransfer() 方法。 你应该 在另一个线程执行这一步,防止阻塞主UI线程。 更多的 在Android使用线程的信息,明白了 流程和 线程 

下面的代码片段是一个微不足道的方式同步数据传输。 你的代码 应该有更多的逻辑来正确地找到正确的接口和通信端点 也应该做任何传输的数据比主UI线程在一个不同的线程:

private Byte[] bytes;private static int TIMEOUT = 0;private boolean forceClaim = true;...UsbInterface intf = device.getInterface(0);UsbEndpoint endpoint = intf.getEndpoint(0);UsbDeviceConnection connection = mUsbManager.openDevice(device); connection.claimInterface(intf, forceClaim);connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT); //do in another thread

异步发送数据,使用 UsbRequest 类 初始化 和 队列 一个异步请求,然后等待结果 与 requestWait() 

有关更多信息,请参见 AdbTest样本 ,它显示了如何去做 异步批量转移, MissileLauncher样本 ,这 异步显示了如何监听一个中断端点。

终止与设备通信

当你完成与设备或通信如果分离设备,关闭 UsbInterface 和 UsbDeviceConnection 通过 调用releaseInterface() 和 close() 。 监听分离的事件, 创建一个广播接收器像下图:

BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {    public void onReceive(Context context, Intent intent) {        String action = intent.getAction();       if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {            UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);            if (device != null) {                // call your method that cleans up and closes communication with the device            }        }    }};

创建应用程序内的广播接收器,而不是清单,允许你 它运行时应用程序只处理分离事件。 这种方式,分离事件 只发送给当前正在运行的应用程序,而不是广播给所有的应用程序。


0 0
原创粉丝点击