关于Android usb host 总结

前段时间因为项目需要,做了一段时间关于Android USB Host的开发,最近闲下来总结一下。

Android模拟器无法测试USB,大部分的平板都不能使用usb host api,这里使用的测试平板是华硕的TF101,有一款可以测试Android平板是否支持USB HostAPI的apk http://download.csdn.net/download/limitemp/4837706

使用usb host api的使用步骤:

注册广播:

AndroidManifest.xml
      <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>
device_filter.xml
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <usb-device vendor-id="1234" product-id="5678" />
</resources>

代码中:

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 closescommunication with the device
            }
        }
    }
};

 

上面的语句主要是为了向系统注册广播,当有USB设备插入的时候系统会弹出提示,如:


vendor-idproduct-id是需要提示的usb设备的两个属性,这些属性可是使用一些USB查看工具来获取,xp下有一个USBtrace挺好用。如果这里什么都不写,则表示对于任何插入的USB设备都会有提示(其实并非任何例如键盘鼠标这类的HID设备就会提示)。

1.  获取UsbManager:

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);

2.  获取设备列表:

HashMap<String, UsbDevice> deviceList = manager.getDeviceList();

3.  通过UsbDevice来获得USBInterface:

UsbInterface getInterface(int index);

获取Interface以后可以根据其类型判断该USB设备的类型

Int getInterfaceClass();返回值为Int类型可以在UsbConstants类中找到对应的值例如:

public static final intUSB_CLASS_AUDIO

USB class for audio devices.

Constant Value: 1 (0x00000001)

该设备为audio设备,int值为1;

4.   根据获得的Interface获取Endpoint:

Endpoint的传输方向有两种,一种是In,一种是Out;对于Android为Host模式来说,in就是传向Host设备的,out是传向Device的;同时Endpoint分为四种类型:USB_ENDPOINT_XFER_CONTROL (endpoint zero)

USB_ENDPOINT_XFER_ISOC (isochronousendpoint)

USB_ENDPOINT_XFER_BULK (bulkendpoint)

USB_ENDPOINT_XFER_INT (interruptendpoint)

分别为对应四种不同的传输类型:控制传输,实时传输,批量传输,中断传输。

根据不同的传输类型选择不同的方法去传输数据。在UsbRequest中有这样一段话:

UsbRequests can beused to transfer data on bulk and interrupt endpoints. Requests on bulkendpoints can be sent synchronously via bulkTransfer(UsbEndpoint, byte[],int, int) or asynchronously via queue(ByteBuffer, int) and requestWait().Requests on interrupt endpoints are only send and received asynchronously.

Requests onendpoint zero are not supported by this class; use controlTransfer(int,int, int, int, byte[], int, int) for endpoint zero requests instead.

就是说对于bulkendpoint可是使用bulkTransfer方法同步传输或者使用queue和requestWait方法异步传输,但是对于interrupt endpoint使用Request只能进行异步传输。而对于endpoint zero端口只能使用controlTransfer方法。所以要根据自己的端口类型来选择合适的方法来传输,否则可能接收不到数据。

例如使用的USB设备的端口类型为bulk endpoint所以直接使用bulkTransfer方法就行了。过程如下:
UsbDeviceConnection connection = mUsbManager.openDevice(device);

//device 为你要打开的设备,这里涉及权限的问题,下面再说
connection.claimInterface(intf, forceClaim);
connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT)

//endpoint如果要接收数据就选择In端口,发送数据选择Out端口,同事这个方法是个阻塞式的方法,所以应该放到其他的线程中。

5.  关于UsbDeviceConnection connection = mUsbManager.openDevice(device);权限的问题:

SDK中有说明,如果设备是通过系统广播的形式获得,则不需要权限就可以直接打开。如果设备是通过manager.getDeviceList();枚举的方式获得,则在打开设备的时候需要权限。SDK中有这样一段代码:

UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
private staticfinalString 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);

当运行到openDevice()时,系统会检查应用程序是否存在权限,若没有则会弹出用户授权的对话框。同意则打开成功,否则失败提示没有权限
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值