Android USB Host 使用详解(U盘)(二)

上一篇介绍了读取Android手机连接的USB设备信息的例子,本篇介绍官方文档中关于USB的API:官方API。注:主要介绍关于Host Mode的。

1)UsbAccessory

用于代表USB从设备的一个类,这个从设备通过USB数据线与Android应用进行通信。

 

2)UsbConfiguration

用于代表USB设备(指连接Android手机的USB从设备)配置信息的一个类。

 

3)UsbConstants

这个类主要包含USB协议常量的类,这些常量与Linux内核下linux/usb/ch9.h 里面定义的相对应。

 

4)UsbDevice

这个类代表在Host Mode下,连接Android手机的USB设备的类。

equals(object) : 用于判断本设备是否与object相等,在编程时判断两个设备是否为同一设备时会用到。

其余的get函数都是返回相应的值。如:getDeviceProtocol()返回代表协议的常量,getDeviceProtocol()==UsbConstants.USB_CLASS_HID则说明此设备为HID设备。

getInterfaceCount():返回设备的接口总数。对于U盘的接口数为1。

getInterface():获取接口(UsbInterface)。

 

5)UsbInterface

这个类代表USB设备上的一个接口。一个USB设备可以有1个或多个接口,每个接口提供不同的功能。一个接口又有1个或者多个端点(UsbEndpoint),端点是用于数据或者命令传输的通道。

getEndpointCount():返回此接口的端点数。对于U盘,返回的端点数为2(用上一篇博客介绍的方法可得)。

getEndpoint(index):返回对应的端点。

 

6)UsbEndpoint

这个类代表接口上的一个端点。端点是用于数据传输的通道。典型的bulk端点用于传输大量的数据,interrupt端点用于传输小量数据,如事件,与数据流分开传输。在官方文档中说端点0是用于传输控制信息的,而端点0是所有USB设备都默认拥有的。但是这个端点0并不会被枚举出来,也就是说,要传输control信息直接用controlTransfer()传输即可,不要试图打开端点0后再进行传输。举个例子:大家所熟悉的U盾,为HID设备,拥有一个接口,缺省的控制端点;用getInterface(0)获取接口0,在getEndpointCount()返回的值为0,端点数为0;控制端点没有被枚举出来。再如U盘有一个接口,拥有控制端点,bulk-in端点,bulk-out端点,总共3个,但是getEndpointCount()返回的值是2。还有鼠标键盘等HID设备为单向传输设备,不能被获取到。

注:在Google API中提到的endpoint 0特指控制端点,而不是指端点号为0的端点。

 

7)UsbManager

这个类允许你获取USB的状态并和USB设备进行通信。

openDevice(),打开要进行通信的USB设备,返回一个UsbDeviceConnection对象。

在使用UsbDeviceConnection对象进行通信前,必须获取权限(获取使用者的同意)。使用

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
获取UsbManager对象,用hasPremission()判断设备是否拥有权限,如果没有,使用如下方法获取权限

mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
mUsbManager.requestPermission(mUsbDevice, mPermissionIntent); 


    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) {
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    	// 获取权限后的操作
                    } 
                    else {
                        finish();
                    }
                }
            }
        }
    };

8)UsbRequest

一个代表请求传输数据包的类。UsbRequest类可以用于在bulk端点和interrupt端点传输数据。control信息的传输不可使用此类。


9)UsbDeviceConnection

这个类用于在Android手机从USB设备接收和发送控制信息和数据信息。此类由openDevice()创建。

bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)

这个函数用于数据传输的。

      endpoint 为传输端点,注意端点的方向。

      buffer 为传输的数据,至于传输数据的格式,需要了解手中的设备具体PDF,不然发送的数据是无意义的,并且无法接收数据。

      length 为buffer的长度。

      timeout 为有效时间(设为0可能导致程序意外终止退出)。

返回值传输的数据的长度,小于0说明传输失败。

controlTransfer (int requestType, int request, int value, int index, byte[] buffer, int length, int timeout)

这个函数用于控制信息的传输,后面三个参数与上面相同。

      requestType 为请求类型,低8位为有效的,第7为表示方向如0x00为发送数据,0x80为接收数据,接收数据时,buffer要有足够的长度。其余7位的设置根据手中设备提供的文档进行设置。(具体值都会在设备文档中给出

      request 与上面的request对应。(具体值都会在设备文档中给出

      value 与上面两个参数对应。(具体值都会在设备文档中给出

      index 表示使用的接口号。(具体值都会在设备文档中给出

HID设备文档下载地址:HID设备文档

U盘设备文档下载地址:U盘bulk-only传输文档

(1)建立连接(HID设备)

	private void makeConnection() {
		if(mUsbDevice == null) {
			Toast.makeText(this, R.string.no_device, Toast.LENGTH_SHORT).show();
        	finish();
			return;
		}
		if(mUsbDevice.getInterfaceCount() != 1) {
			Toast.makeText(this, R.string.interface_error, Toast.LENGTH_SHORT).show();
			finish();
			return;
		}
		
		UsbInterface intf = mUsbDevice.getInterface(0);
						
		if (mUsbDevice != null) {
            UsbDeviceConnection connection = mUsbManager.openDevice(mUsbDevice);
            if (connection != null && connection.claimInterface(intf, true)) {
            	Toast.makeText(this, R.string.connection_fine, Toast.LENGTH_SHORT).show();
                mConnection = connection;
            } else {
            	Toast.makeText(this, R.string.connection_error, Toast.LENGTH_SHORT).show();
                mConnection = null;
                finish();
            }
         }
	}
(2)发送控制信息(mCmd[8]请根据自己的设备进行设置)

	private void sendCommand() {
		
		synchronized (this) {
            if (mConnection != null) {
            	mCmd = new byte[8];
            	mCmd[0] = (byte) 0x00; //请自行设置
            	mCmd[1] = (byte) 0x00;
            	mCmd[2] = (byte) 0x00;
            	mCmd[3] = (byte) 0x00;
            	mCmd[4] = (byte) 0x00;
            	mCmd[5] = (byte) 0x00;
            	mCmd[6] = (byte) 0x00;
            	mCmd[7] = (byte) 0x00;
            	
                int result = mConnection.controlTransfer(0x21, 0x09, 0x0300, 0x00, mCmd, mCmd.length, 1000);
                if(result < 0) {
    				Toast.makeText(this, R.string.send_command_failed, Toast.LENGTH_SHORT).show();
    			} else {
    				Toast.makeText(this, R.string.send_command_successed, Toast.LENGTH_SHORT).show();
    			}    	
            }
        }
	}
(3)根据发送的控制信息,接收控制信息的结果(HID设备)

private void recvMessage() {
		
		synchronized (this) {
            if (mConnection != null) {
            	byte[] message = new byte[32];
                int result = mConnection.controlTransfer(0xA1, 0x01, 0x0300, 0x00, message, message.length, 1000);
                
                if(result < 0) {
    				Toast.makeText(this, R.string.recv_message_failed, Toast.LENGTH_SHORT).show();
    				mMessageView.setText(R.string.string_null);
    			} else {
    				Toast.makeText(this, R.string.recv_message_successed, Toast.LENGTH_SHORT).show();
    				String str = new String();
    				for(int i=0; i<message.length; i++) {
    					str += Integer.toHexString(message[i]&0x00FF)  + " ";
    				}
    				mMessageView.setText(str);
    			}
            }
        }
	}


上面是我U盾操作中截取的,请原谅我不能公开命令参数!

Android USB Host的API的简要介绍就到这里,不明白的请看下一篇:Android bulk-only U盘操作实例




发布了13 篇原创文章 · 获赞 8 · 访问量 7万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览