USB Host

  USB Host,中文意思是USB主模式,是相对于USB accessory(USB副模式)来说的,前者是在android设备上插入一USB设备,android设备做为主机运行;后者也是在android设备上通过USB数据线插入另外一个设备,但插入的设备可以是一个完整的独立主机,也就是可以是另外一个android设备。需要注意的是以上两种模式在android API level-12以下是不支持的,也就是说只有android3.1及更高的版本才支持这两种模式,下面对USB主模式做一简介:

1.UsbManager
负责管理USB设备的类,你可以在相应代码中通过以下方法获得此对象的一个实例:UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
该类提供的主要方法有:

  1. getDeviceList()
    获得设备列表,返回的是一个HashMap.;
  2. hasPermission(UsbDevice device)
    判断你的应用程序是否有接入此USB设备的权限,如果有则返回真,否则返回false.
  3. openDevice(UsbDevice device)
    打开USB设备,以便向此USB设备发送和接受数据,返回一个关于此USB设备的连接。
  4. requestPermission(UsbDevice device, PendingIntent pi)
    向USB设备请求临时的接入权限。

2.UsbDevice
代表一个USB设备的类,每个设备都包含了一个或多个接口,每个接口又包含一个或多个节点用来与此设备传输数据。该类的主要方法有:
1) getDeviceClass()
返回此USB设备的类别,用一个整型来表示。
2) getDeviceId()
返回唯一标识此设备的ID号,也用一个整型来表示。

  1. getDeviceName()
    返回此设备的名称,用一个字符串来表示。

  2. getDeviceProtocol()
    返回此设备的协议类别,用一个整型来表示。

    1. getDeviceSubclass()
      返回此设备的子类别,用一个整型来表示。
  3. getVendorId()
    返回生产商ID

  4. getProductId()
    返回产品ID

  5. getInterfaceCount()
    返回此设备的接口数量

  6. getInterface(int index)
    得到此设备的一个接口,返回一个UsbInterface。
    3.UsbInterface
    代表USB设备的一个接口,注意:UsbInterface本身是一个类,并不是一个接口。此类的主要方法有以下:

  7. getId()
    得到给接口的id号。

  8. getInterfaceClass()
    得到该接口的类别。

  9. getInterfaceSubclass()
    得到该接口的子类。

  10. getInterfaceProtocol()
    得到该接口的协议类别。

  11. getEndpointCount()
    获得关于此接口的节点数量。

  12. getEndpoint(int index)
    对于指定的index获得此接口的一个节点,返回一个UsbEndpoint.
    4.UsbEndpoint
    代表一个接口的某个节点的类。该类主要提供了一下方法供你使用:

  13. getAddress()
    获得此节点的地址

  14. getAttributes()
    获得此节点的属性

  15. getDirection()
    获得此节点的数据传输方向
    5.UsbDeviceConnection
    代表USB连接的一个类。用此连接可以想USB设备发送和接收数据,可以通过调用该方法openDevice(UsbDevice) 来得到该类的一个实例。该类提供了以下方法供你使用:
    1)bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)
    通过给定的endpoint来进行大量的数据传输,传输的方向取决于该节点的方向,buffer是要发送或接收的字节数组,length是该字节数组的长度。传输成功则返回所传输的字节数组的长度,失败则返回负数。
    2)controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int length, int timeout)
    该方法通过0节点向此设备传输数据,传输的方向取决于请求的类别,如果requestType为USB_DIR_OUT则为写数据,USB_DIR_IN, 则为读数据
    Android配置文件要求
    在你使用以上API进行开发之前,你需要在你的AndroidManifest.xml文件中添加以下内容:
    1.因为并不能保证所有的安卓设备都支持以上API,所以你需要声明:
    12以下的版本是不支持以上APId的。


2.如果你想有一个USB设备接入你的安卓设备时能够通知你的应用程序,那么你需要在你的Activity标签中声明以下内容


Resource属性指定了要过滤的数据设备信息,包括:
1) vendor-id 设备生产商id
2) product-id 设备id
3) class 设备类别
4) subclass 设备子类
5) protocol(device or interface) 协议类别
device_filter.xml文件放在res\xml目录下,其中文件名不包括扩展名部分需要与 标签中声明的一致。示例如下:
<?xml version="1.0" encoding="utf-8"?>




开发步骤
1.检测设备
你的应用可以通过两种方式来发现USB设备,一种是用一个意图过滤器在用户连接一个设备时对其进行通知,另一种则是通过枚举您已经连接的所有USB设备。如果你希望你的应用能够自动的探测到你想要的设备,请使用一个意图过滤器来做。但是,如果你希望得到一个已连接设备的列表或者你不希望过滤意图,枚举所有的设备会是一个更好的选择。
1)Intent Filter

为了让应用可以发现一个特定的USB设备,你可以为android.hardware.usb.action.USB_DEVICE_ATTACHED这个意图指定一个意图来进行过滤。伴随着这个意图过滤器,您需要指定一个资源文件来特别说明这个USB设备的属性,例如供应商和产品ID。当用户连接到一个符合你配件过滤条件的配件时,这个系统会谈出一个对话框询问他们是否希望开始你的应用。如果用户同意,那么你的应用在失去连接之前会自动获取和设备连接的权限。
下面的例子告诉你该如何声明这个意图过滤器:

...


android:resource="@xml/device_filter" />

下面的例子告诉你怎么样声明指定你希望连接的USB设备的相关资源文件:
<?xml version="1.0" encoding="utf-8"?>

 2)列举设备       你可以通过UsbMnanger来列举已经连接的USB设备:代码如下       首先,得到UsbMnanger的一个实例

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
其次,通过此类的getDeviceList()方法得到包含所有已连接的USB设备的列表
HashMap deviceList = manager.getDeviceList();
最后,通过设备名称来得到给设备对象
UsbDevice device = deviceList.get("deviceName");
如果你想一个一个的列举所有的设备,可以实用迭代器,代码实例如下:
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap deviceList = manager.getDeviceList();
Iterator deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next()
//在这里添加处理设备的代码
}
2.获得和设备通信的权限
如果你实用intent filter来发现一个USB设备,即上述方法1)那么应用程序可以自动的获取权限;
如果是使用方法2)来检测USB设备,则你需要显示声明权限。其步骤如下:
首先:创建一个广播接收器,接受请求权限的广播,代码如下:
private static final String ACTION_USB_PERMISSION =private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
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){
//在这里增加通信的代码
}}}}}};

     然后:在你的主Activity中注册该广播接收器,代码如下:

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() 来显示询问对话框,即在上面红线处添加如下代码:
mUsbManager.requestPermission(device, mPermissionIntent);
3.和设备通信
Android设备和一个连接它的USB设备通信即可以是同步的也可以使异步的,不管是那种情况,你都应该创建一个新的线程去负责所有的数据传输,以免阻塞UI线程。为了和US B设备建立通信,你首先需要得到合适的接口和节点,然后通过UsbDeviceConnection在此节点上进行数据的传输,由此你的代码应该:
1)检查该USB设备的属性,例如,生产商id,产品id,设备类别,以确定你是否需要和此设备进行通信。
2)当你确定要和此设备进行通信的时候,找到合适的接口和节点。
3)当你找到一个合适的节点后,用UsbDeviceConnection在此节点上打开连接。
4)使用bulkTransfer()或者controlTransfer() 来发送和接收数据。示例代码如下:
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
4.终止通信
当你完成数据的传输或者你的设备已拔出时,通过调用releaseInterface()和 close()来关闭接口和连接。

更多相关文章

  1. Android开发当中Parcelable,Serializable接口的使用
  2. Android解析中国天气接口JSon数据,应用于天气查询!
  3. [置顶] Android系统移植与调试之------->如何修改Android设备存
  4. Android6.0修改设备设置中kernel信息
  5. android 语音识别接口开发。
  6. 【译】Android 23最新接口变化(Android API Differences Report)
  7. 查看当前android设备api版本
  8. Android设备抓包命令
  9. Android使用adb命令行卸载手机设备上的应用

随机推荐

  1. 【Android】获取设备型号、SDK版本及其系
  2. Cocos2d-x 导入到Eclipse后出现The impor
  3. Arcgis Android(安卓)定位
  4. Android权限探究——获取正在运行的应用/
  5. Android下的默认字体详解
  6. Android(安卓)Studio 四大组件之 Service
  7. activity介绍和值的传递(寒假学习2)
  8. Android(安卓)Studio打包jar教程
  9. Android(安卓)播放视频常见问题小结
  10. EditText设置可以编辑和不可编辑状态