USB host 通信

来源:互联网 发布:逍遥模拟器优化cpu 编辑:程序博客网 时间:2024/06/07 22:52

公司主打支付产品,产品是和Android平板连接起来的。Android平板怎么和产品通信呢?串口或者USB口。串口通信比较简单,下篇再讲,此篇主要讲的是usb host通信。

一:寻找UsbDevice并授权

两种方法寻找usb device,1是通过Intent Filter来寻找,2是通过枚举所有的设备来寻找

1.在manifest文件中添加如下代码:

<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>

然后再res文件夹下创建一个device_filter.xml文件如下 :

<?xml version="1.0" encoding="utf-8"?><resources>   <usb-device vendor-id="1411" product-id="22336"  /></resources>
然后在包含此Intent Filter的activity中通过如下方法就可以得到已经授权的USBDevice了

Intent intent = getIntent();UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
当用户在已经打开此应用的平板中插入产品模块的时候,此activity会自动打开并弹出对话框,“是否授权usb读写权限”,当用户点击“是”时,此应用就会得到应用授权的UsbDevice。

2.通过枚举所有的设备来寻找

mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);getUsbDevice(mUsbManager);......private void getUsbDevice(UsbManager mUsbManager) {HashMap<String, UsbDevice> devicesList = mUsbManager.getDeviceList();Iterator<UsbDevice> deviceIterator = devicesList.values().iterator();while(deviceIterator.hasNext()) {UsbDevice usb = deviceIterator.next();if(usb.getProductId()==0x5740 && usb.getVendorId()==0x0583) {usbDevice = usb;}}}
但是通过此方法寻找出来的usbDevice并没有得到授权,所以需要在此之上进行授权,怎么授权,如下:

mUsbReceiver = new UsbReceiver();IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);registerReceiver(mUsbReceiver, filter);mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);mUsbManager.requestPermission(usbDevice, mPermissionIntent);
mUsbManager调用方法 requestPermission() 将弹出对话框,以询问用户是授权应用。广播接收类如下:

private class UsbReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent){// TODO Auto-generated method stubString action = intent.getAction();if (ACTION_USB_PERMISSION.equals(action)) {synchronized (this) { usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);boolean usbPremission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);if((usbPremission) && (usbDevice != null)){findEndPoint();openDevice(localUsbInterface);}else {}}} else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if(usbDevice != null){        }else{}if (!mUsbManager.hasPermission(usbDevice)) {mUsbManager.requestPermission(usbDevice, mPermissionIntent);}} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);}}}

二:找到智能卡接口(UsbInterface)并找到此接口中的输入,输出等端口(UsbEndpoint)

public void findEndPoint()    {    int countInterface = usbDevice.getInterfaceCount();    Log.i("kejian","countInterface = "+countInterface);    int i=0;    int interfaceClass=0;    for(i=0;i<countInterface;i++)    {     localUsbInterface= usbDevice.getInterface(i);     interfaceClass=localUsbInterface.getInterfaceClass();     //如果当前接口不是智能卡接口,则不处理      if(interfaceClass!=0x0B)     continue;    int countEndpoint=localUsbInterface.getEndpointCount();    UsbEndpoint localUsbEndpoint;    for(int j=0;j<countEndpoint;j++)    {        localUsbEndpoint=localUsbInterface.getEndpoint(j);        int typeEndpoint=localUsbEndpoint.getType();//    端点类型为2,批量传输    if(typeEndpoint==2)    {    if(localUsbEndpoint.getDirection()==0)    {    //localObject1是输出端点    if(localObject1==null)    localObject1=localUsbEndpoint;    }    else if(localObject2==null)    {    //localObject2是输入端点    localObject2=localUsbEndpoint;    }    }    else    {    //端点类型为3,中断方式    if(typeEndpoint!=3)    continue;    if((localUsbEndpoint.getDirection()!=0x80)||(localObject3!=null))    {    continue;    }    localObject3=localUsbEndpoint;    }    }    }    }

三:打开此端口

public void openDevice(UsbInterface mInterface) {          if (mInterface != null) {              UsbDeviceConnection conn = null;              // 在open前判断是否有连接权限;对于连接权限可以静态分配,也可以动态分配权限              if (mUsbManager.hasPermission(usbDevice)) {                  conn = mUsbManager.openDevice(usbDevice);              }                if (conn == null) {                  return;              }                if (conn.claimInterface(mInterface, true)) {                  myDeviceConnection = conn;                  if (myDeviceConnection != null)// 到此你的android设备已经连上zigbee设备                      System.out.println("open设备成功!");                  final String mySerial = myDeviceConnection.getSerial();                  System.out.println("设备serial number:" + mySerial);              } else {                  System.out.println("无法打开连接通道。");                  conn.close();              }          }      }
经过上面这些步骤,接下来就可以进行通信了

Button trans_btn = (Button) this.findViewById(R.id.trans);trans_btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubnew Thread(new Runnable(){@Overridepublic void run() {trans();}}).start();}});

通信方法如下:

public void trans() {int status = myDeviceConnection.bulkTransfer((UsbEndpoint)localObject1, USB_CARD_SWING_COMMAND, USB_CARD_SWING_COMMAND.length, 6000);byte []tmpRecv=new byte[2048];    status=myDeviceConnection.bulkTransfer((UsbEndpoint)localObject2,tmpRecv ,tmpRecv.length, 60000);Log.d(TAG,"recv len = "+status);byte []dataReturn=new byte[status];    System.arraycopy(tmpRecv, 0, dataReturn, 0, status);        Log.d(TAG,"sendApdu Recv = "+Utils.bytesToHexStr(dataReturn, 0,  status));}
第一个bulkTransfer方法是给产品模块发送数据,产品模块对此数据进行处理之后,会返回数据,这里的第二个bulkTransfer方法就是用来接收数据的,根据log信息显示的是正确的返回信息。


参考资料:

http://blog.csdn.net/halsonhe/article/details/46648699

http://blog.csdn.net/wizardmly/article/details/8350137



关于usb host通信说的比较详细的blog系列:http://www.cnblogs.com/sowhat4999/p/4439877.html






0 0