您的位置:首页 > 移动开发 > Android开发

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

2016-04-29 10:19 591 查看



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系统可以确定 您的应用程序是否感兴趣的连接设备。 如果是这样,您可以设置 与设备如果需要沟通。 要做到这一点,您的应用程序有:
发现连接USB设备通过使用一个意图过滤器时通知用户 连接USB设备或通过列举USB设备已经连接。
要求用户允许连接到USB设备,如果不是已经获得。
与读写数据的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
            }
        }
    }
};

创建应用程序内的广播接收器,而不是清单,允许你 它运行时应用程序只处理分离事件。 这种方式,分离事件 只发送给当前正在运行的应用程序,而不是广播给所有的应用程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  USB Host模式