USB host 通信

本文详细介绍了如何在Android平板上实现USB Host通信。包括通过Intent Filter或枚举设备来寻找USB设备,授权过程,找到智能卡接口及端口,以及打开端口进行数据收发的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

一:寻找UsbDevice并授权

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

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

[java]  view plain  copy
  1. <activity ...>  
  2.     ...  
  3.     <intent-filter>  
  4.         <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />  
  5.     </intent-filter>  
  6.     <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />  
  7. </activity>  

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

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

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

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

[html]  view plain  copy
  1. mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);  
  2. getUsbDevice(mUsbManager);  
  3. ......  
  4. private void getUsbDevice(UsbManager mUsbManager)   
  5.     {  
  6.         HashMap<String, UsbDevice> devicesList = mUsbManager.getDeviceList();  
  7.         Iterator<UsbDevice> deviceIterator = devicesList.values().iterator();  
  8.           
  9.         while(deviceIterator.hasNext())   
  10.         {  
  11.             UsbDevice usb = deviceIterator.next();  
  12.             if(usb.getProductId()==0x5740 && usb.getVendorId()==0x0583)   
  13.             {  
  14.                 usbDevice = usb;  
  15.             }  
  16.         }  
  17.     }  
但是通过此方法寻找出来的usbDevice并没有得到授权,所以需要在此之上进行授权,怎么授权,如下:

[java]  view plain  copy
  1. mUsbReceiver = new UsbReceiver();  
  2. IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);  
  3. filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);  
  4. filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);  
  5. registerReceiver(mUsbReceiver, filter);  
  6. mPermissionIntent = PendingIntent.getBroadcast(this0new Intent(ACTION_USB_PERMISSION), 0);  
  7. mUsbManager.requestPermission(usbDevice, mPermissionIntent);  
mUsbManager调用方法  requestPermission()  将弹出对话框,以询问用户是授权应用。广播接收类如下:

[java]  view plain  copy
  1. private class UsbReceiver extends BroadcastReceiver  
  2.     {  
  3.   
  4.         @Override  
  5.         public void onReceive(Context context, Intent intent)  
  6.         {  
  7.             // TODO Auto-generated method stub  
  8.             String action = intent.getAction();  
  9.             if (ACTION_USB_PERMISSION.equals(action))   
  10.             {                 
  11.                 synchronized (this)   
  12.                 {   
  13.                     usbDevice = (UsbDevice) intent  
  14.                             .getParcelableExtra(UsbManager.EXTRA_DEVICE);  
  15.                     boolean usbPremission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);  
  16.                     if((usbPremission) && (usbDevice != null))  
  17.                     {  
  18.                         findEndPoint();  
  19.                         openDevice(localUsbInterface);  
  20.                     }                     
  21.                     else   
  22.                     {  
  23.                     }  
  24.                 }  
  25.   
  26.             }   
  27.             else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action))   
  28.             {                 
  29.                 usbDevice = (UsbDevice) intent  
  30.                         .getParcelableExtra(UsbManager.EXTRA_DEVICE);  
  31.                 if(usbDevice != null)  
  32.                 {  
  33.                     }  
  34.                 else  
  35.                 {  
  36.                 }  
  37.                 if (!mUsbManager.hasPermission(usbDevice)) {  
  38.                     mUsbManager.requestPermission(usbDevice, mPermissionIntent);  
  39.                 }  
  40.             }   
  41.             else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action))   
  42.             {  
  43.                 usbDevice = (UsbDevice) intent  
  44.                         .getParcelableExtra(UsbManager.EXTRA_DEVICE);  
  45.             }         
  46.           
  47.         }     
  48.     }  

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

[java]  view plain  copy
  1. public void findEndPoint()  
  2.     {  
  3.         int countInterface = usbDevice.getInterfaceCount();  
  4.         Log.i("kejian","countInterface = "+countInterface);  
  5.         int i=0;  
  6.         int interfaceClass=0;  
  7.         for(i=0;i<countInterface;i++)  
  8.         {  
  9.              localUsbInterface= usbDevice.getInterface(i);  
  10.              interfaceClass=localUsbInterface.getInterfaceClass();  
  11.              //如果当前接口不是智能卡接口,则不处理   
  12.              if(interfaceClass!=0x0B)  
  13.                  continue;  
  14.             int countEndpoint=localUsbInterface.getEndpointCount();  
  15.             UsbEndpoint localUsbEndpoint;  
  16.             for(int j=0;j<countEndpoint;j++)  
  17.             {  
  18.                   
  19.                 localUsbEndpoint=localUsbInterface.getEndpoint(j);                
  20.                 int typeEndpoint=localUsbEndpoint.getType();  
  21. //              端点类型为2,批量传输  
  22.                 if(typeEndpoint==2)  
  23.                 {  
  24.                     if(localUsbEndpoint.getDirection()==0)  
  25.                     {  
  26.                         //localObject1是输出端点  
  27.                         if(localObject1==null)  
  28.                             localObject1=localUsbEndpoint;  
  29.                     }  
  30.                     else if(localObject2==null)  
  31.                     {  
  32.                         //localObject2是输入端点  
  33.                         localObject2=localUsbEndpoint;  
  34.                     }  
  35.                 }  
  36.                 else  
  37.                 {  
  38.                     //端点类型为3,中断方式  
  39.                     if(typeEndpoint!=3)  
  40.                         continue;  
  41.                     if((localUsbEndpoint.getDirection()!=0x80)||(localObject3!=null))  
  42.                     {  
  43.                         continue;  
  44.                     }  
  45.                     localObject3=localUsbEndpoint;  
  46.                 }  
  47.             }  
  48.         }  
  49.     }  

三:打开此端口

[java]  view plain  copy
  1. public void openDevice(UsbInterface mInterface) {    
  2.         if (mInterface != null) {    
  3.             UsbDeviceConnection conn = null;    
  4.             // 在open前判断是否有连接权限;对于连接权限可以静态分配,也可以动态分配权限    
  5.             if (mUsbManager.hasPermission(usbDevice)) {    
  6.                 conn = mUsbManager.openDevice(usbDevice);    
  7.             }    
  8.     
  9.             if (conn == null) {    
  10.                 return;    
  11.             }    
  12.     
  13.             if (conn.claimInterface(mInterface, true)) {    
  14.                 myDeviceConnection = conn;    
  15.                 if (myDeviceConnection != null)// 到此你的android设备已经连上zigbee设备    
  16.                     System.out.println("open设备成功!");    
  17.                 final String mySerial = myDeviceConnection.getSerial();    
  18.                 System.out.println("设备serial number:" + mySerial);    
  19.             } else {    
  20.                 System.out.println("无法打开连接通道。");    
  21.                 conn.close();    
  22.             }    
  23.         }    
  24.     }  
经过上面这些步骤,接下来就可以进行通信了

[html]  view plain  copy
  1. Button trans_btn = (Button) this.findViewById(R.id.trans);  
  2.         trans_btn.setOnClickListener(new View.OnClickListener() {  
  3.               
  4.             @Override  
  5.             public void onClick(View v) {  
  6.                 // TODO Auto-generated method stub  
  7.                 new Thread(new Runnable(){  
  8.   
  9.                     @Override  
  10.                     public void run() {  
  11.                         trans();  
  12.                     }  
  13.                 }).start();  
  14.                 }  
  15.         });  

通信方法如下:

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


参考资料:

http://blog.youkuaiyun.com/halsonhe/article/details/46648699

http://blog.youkuaiyun.com/wizardmly/article/details/8350137



关于usb host通信说的比较详细的blog系列:http://www.cnblogs.com/sowhat4999/p/4439877.html
STM32 HOST USB代码 u8 USH_User_App(void) { u32 total,free; u8 res=0; Show_Str(30,140,200,16,"É豸Á¬½Ó³É¹¦!.",16,0); res=exf_getfree("2:",&total,&free); if(res==0) { POINT_COLOR=BLUE;//ÉèÖÃ×ÖÌåΪÀ¶É« LCD_ShowString(30,160,200,16,16,"FATFS OK!"); LCD_ShowString(30,180,200,16,16,"U Disk Total Size: MB"); LCD_ShowString(30,200,200,16,16,"U Disk Free Size: MB"); LCD_ShowNum(174,180,total>>10,5,16); //ÏÔʾUÅÌ×ÜÈÝÁ¿ MB LCD_ShowNum(174,200,free>>10,5,16); } while(HCD_IsDeviceConnected(&USB_OTG_Core))//É豸Á¬½Ó³É¹¦ { LED1=!LED1; delay_ms(200); } POINT_COLOR=RED;//ÉèÖÃ×ÖÌåΪºìÉ« Show_Str(30,140,200,16,"É豸Á¬½ÓÖÐ...",16,0); LCD_Fill(30,160,239,220,WHITE); return res; } int main(void) { u8 t; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é2 delay_init(168); //³õʼ»¯ÑÓʱº¯Êý uart_init(115200); //³õʼ»¯´®¿Ú²¨ÌØÂÊΪ115200 LED_Init(); //³õʼ»¯ÓëLEDÁ¬½ÓµÄÓ²¼þ½Ó¿Ú KEY_Init(); //°´¼ü LCD_Init(); //³õʼ»¯LCD W25QXX_Init(); //SPI FLASH³õʼ»¯ usmart_dev.init(84); //³õʼ»¯USMART my_mem_init(SRAMIN); //³õʼ»¯ÄÚ²¿ÄÚ´æ³Ø exfuns_init(); //ΪfatfsÏà¹Ø±äÁ¿ÉêÇëÄÚ´æ piclib_init(); //³õʼ»¯»­Í¼ f_mount(fs[0],"0:",1); //¹ÒÔØSD¿¨ f_mount(fs[1],"1:",1); //¹ÒÔØSD¿¨ f_mount(fs[2],"2:",1); //¹ÒÔØUÅÌ POINT_COLOR=RED; while(font_init()) //¼ì²é×Ö¿â { LCD_ShowString(60,50,200,16,16,"Font Error!"); delay_ms(200); LCD_Fill(60,50,240,66,WHITE);//Çå³ýÏÔʾ delay_ms(200); } Show_Str(30,50,200,16,"̽Ë÷ÕßSTM32F407¿ª·¢°å",16,0); Show_Str(30,70,200,16,"USB UÅÌʵÑé",16,0); Show_Str(30,90,200,16,"2014Äê7ÔÂ22ÈÕ",16,0); Show_Str(30,110,200,16,"ÕýµãÔ­×Ó@ALIENTEK",16,0); Show_Str(30,140,200,16,"É豸Á¬½ÓÖÐ...",16,0); //³õʼ»¯USBÖ÷»ú USBH_Init(&USB_OTG_Core,USB_OTG_FS_CORE_ID,&USB_Host,&USBH_MSC_cb,&USR_Callbacks); while(1) { USBH_Process(&USB_OTG_Core, &USB_Host); delay_ms(1); t++; if(t==200) { LED0=!LED0; t=0; } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值