糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 获取usb设备类型

获取usb设备类型

时间:2021-08-14 16:45:18

相关推荐

获取usb设备类型

项目中需要区分USB的连接设备是打印机还是电子秤,然后上网搜索到了一篇博客,根据这个博客写的一个小的例子:非常感谢hao_的这篇博客/u013686019/article/details/50409421

MainActivity:

[java]view plain copy packagecom.example.administrator.usbmanagertest; importandroid.content.Context; importandroid.hardware.usb.UsbDevice; importandroid.hardware.usb.UsbInterface; importandroid.hardware.usb.UsbManager; importandroid.support.v7.app.AppCompatActivity; importandroid.os.Bundle; importandroid.view.View; importandroid.widget.TextView; importjava.util.HashMap; importjava.util.Iterator; publicclassMainActivityextendsAppCompatActivity{ privateTextViewtextView; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView=(TextView)findViewById(R.id.sb); } publicvoidshowUsbList(Viewview){ UsbManagermanager=(UsbManager)getSystemService(Context.USB_SERVICE); HashMap<String,UsbDevice>deviceList=manager.getDeviceList(); Iterator<UsbDevice>deviceIterator=deviceList.values().iterator(); StringBuildersb=newStringBuilder(); while(deviceIterator.hasNext()){ UsbDeviceusbDevice=deviceIterator.next(); sb.append("DeviceName="+usbDevice.getDeviceName()+"\n"); sb.append("DeviceId="+usbDevice.getDeviceId()+"\n"); sb.append("VendorId="+usbDevice.getVendorId()+"\n"); sb.append("ProductId="+usbDevice.getProductId()+"\n"); sb.append("DeviceClass="+usbDevice.getDeviceClass()+"\n"); intdeviceClass=usbDevice.getDeviceClass(); if(deviceClass==0){ UsbInterfaceanInterface=usbDevice.getInterface(0); intinterfaceClass=anInterface.getInterfaceClass(); sb.append("deviceClass为0-------------\n"); sb.append("Interface.describeContents()="+anInterface.describeContents()+"\n"); sb.append("Interface.getEndpointCount()="+anInterface.getEndpointCount()+"\n"); sb.append("Interface.getId()="+anInterface.getId()+"\n"); ///u013686019/article/details/50409421 ///developers/defined_class/#BaseClassFFh //通过下面的InterfaceClass来判断到底是哪一种的,例如7就是打印机,8就是usb的U盘 sb.append("Interface.getInterfaceClass()="+anInterface.getInterfaceClass()+"\n"); if(anInterface.getInterfaceClass()==7){ sb.append("此设备是打印机\n"); }elseif(anInterface.getInterfaceClass()==8){ sb.append("此设备是U盘\n"); } sb.append("anInterface.getInterfaceProtocol()="+anInterface.getInterfaceProtocol()+"\n"); sb.append("anInterface.getInterfaceSubclass()="+anInterface.getInterfaceSubclass()+"\n"); sb.append("deviceClass为0------end-------\n"); } sb.append("DeviceProtocol="+usbDevice.getDeviceProtocol()+"\n"); sb.append("DeviceSubclass="+usbDevice.getDeviceSubclass()+"\n"); sb.append("+++++++++++++++++++++++++++\n"); sb.append("\n"); } textView.setText(sb); } }

activity_main.xml

[html]view plain copy <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="/apk/res/android" xmlns:tools="/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.administrator.usbmanagertest.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="showUsbList" android:text="ShowUSBList"/> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:textSize="25sp" android:id="@+id/sb" android:layout_width="match_parent" android:layout_height="wrap_content"/> </ScrollView> </LinearLayout>

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

参考博客地址:

/u013686019/article/details/50409421

一、问题

现在有USB设备插入Android系统,那么如何得知插入的设备类型?是USB打印机,U盘,还是USB鼠标

二、USB类型规定

对于USB类型,USB组织是有规定的,见:/

比如:

三、Linux对USB设备类型定义

在kernel中,有两个结构体的相关成员表征USB设备的类型,第一个usb_device_descriptor

[cpp]view plain copyinclude/uapi/linux/usb/ch9.h /*USB_DT_DEVICE:Devicedescriptor*/ structusb_device_descriptor{ __u8bDeviceClass; __u8bDeviceSubClass; __u8bDeviceProtocol; }__attribute__((packed));bDeviceClass成员值区别不同的USB设备,如果该值为0呢?看上边:

就在第二个结构体usb_interface_descriptor中:

[cpp]view plain copyinclude/uapi/linux/usb/ch9.h structusb_interface_descriptor{ __u8bInterfaceClass; __u8bInterfaceSubClass; __u8bInterfaceProtocol; }__attribute__((packed));bInterfaceClass成员即是。

比如,对于USB打印机设备,定义如下:

[cpp]view plain copyinclude/uapi/linux/usb/ch9.h /* *Deviceand/orInterfaceClasscodes *asfoundinbDeviceClassorbInterfaceClass *documents */ #defineUSB_CLASS_PER_INTERFACE0/*forDeviceClass*/ #defineUSB_CLASS_AUDIO1 #defineUSB_CLASS_COMM2 #defineUSB_CLASS_HID3 #defineUSB_CLASS_PHYSICAL5 #defineUSB_CLASS_STILL_IMAGE6 #defineUSB_CLASS_PRINTER7 #defineUSB_CLASS_MASS_STORAGE8 #defineUSB_CLASS_HUB9 #defineUSB_CLASS_CDC_DATA0x0a #defineUSB_CLASS_CSCID0x0b/*chip+smartcard*/ #defineUSB_CLASS_CONTENT_SEC0x0d/*contentsecurity*/ #defineUSB_CLASS_VIDEO0x0e #defineUSB_CLASS_WIRELESS_CONTROLLER0xe0 #defineUSB_CLASS_MISC0xef #defineUSB_CLASS_APP_SPEC0xfe #defineUSB_CLASS_VENDOR_SPEC0xff drivers/usb/gadget/printer.c staticstructusb_interface_descriptorintf_desc={ .bLength=sizeofintf_desc, .bDescriptorType=USB_DT_INTERFACE, .bNumEndpoints=2, .bInterfaceClass=USB_CLASS_PRINTER, .bInterfaceSubClass=1,/*PrinterSub-Class*/ .bInterfaceProtocol=2,/*Bi-Directional*/ .iInterface=0 }; 对上了,不是?!

四、HAL层和Framework层

HAL层的usbhost.c文件为我们获取Linuxdriver中USB设备的信息提供了便利,除了USB设备类型,还可以得到USB设备的厂商名称、产品名称、序列号等:

system/core/libusbhost/usbhost.c

usbhost.c该文件中提供的方法在JNI中调用:

frameworks/base/services/jni/com_android_server_UsbHostManager.cpp

上面代码截图信息量很大!很重要!很重要!很重要!很重要!重要的地方说四遍。

1、调用usbhost.c文件中方法获取USB设备信息

2、获取的信息一部分传到UsbInterface.Java,APP部分调用UsbInterface类获取信息

[java]view plain copyframeworks/base/core/java/android/hardware/usb/UsbInterface.java publicclassUsbInterfaceimplementsParcelable{ privatefinalintmId; privatefinalintmClass; privatefinalintmSubclass; privatefinalintmProtocol; privatefinalParcelable[]mEndpoints; } 3、 获取的信息另一部分通过调用UsbHostManager.java中的usbDeviceAdded()方法,把信息写到UsbDevice.java中, APP部分调用UsbDevice类获取信息[java]view plain copyframeworks/base/core/java/android/hardware/usb/UsbDevice.java publicclassUsbDeviceimplementsParcelable{ privatefinalStringmName; privatefinalintmVendorId; privatefinalintmProductId; privatefinalintmClass; privatefinalintmSubclass; privatefinalintmProtocol; privatefinalParcelable[]mInterfaces; } 接下来,我们就看下如此关键的 usbDeviceAdded()方法:[java]view plain copyframeworks/base/services/java/com/android/server/usb/UsbHostManager.java /*CalledfromJNIinmonitorUsbHostBus()toreportnewUSBdevices*/ privatevoidusbDeviceAdded(StringdeviceName,intvendorID,intproductID, intdeviceClass,intdeviceSubclass,intdeviceProtocol, /*arrayofquintuplescontainingid,class,subclass,protocol andnumberofendpointsforeachinterface*/ int[]interfaceValues, /*arrayofquadruplescontainingaddress,attributes,maxpacketsize andintervalforeachendpoint*/ int[]endpointValues){ synchronized(mLock){ for(intf=0;intf<numInterfaces;intf++){ intinterfaceId=interfaceValues[ival++]; intinterfaceClass=interfaceValues[ival++]; intinterfaceSubclass=interfaceValues[ival++]; intinterfaceProtocol=interfaceValues[ival++]; intnumEndpoints=interfaceValues[ival++]; interfaces[intf]=newUsbInterface(interfaceId,interfaceClass, interfaceSubclass,interfaceProtocol,endpoints); } UsbDevicedevice=newUsbDevice(deviceName,vendorID,productID, deviceClass,deviceSubclass,deviceProtocol,interfaces); mDevices.put(deviceName,device); } }

五、APP层

经过上面分析,获取USB设备类型等信息,已经心有成竹了,使用UsbDevice、UsbInterface两个类即可。其中, UsbInterface类是包含在 UsbDevice类中的:[java]view plain copyframeworks/base/core/java/android/hardware/usb/UsbDevice.java publicclassUsbDeviceimplementsParcelable{ privatefinalParcelable[]mInterfaces; /** *Returnsthe{@linkUsbInterface}atthegivenindex. * *@returntheinterface */ publicUsbInterfacegetInterface(intindex){ return(UsbInterface)mInterfaces[index]; } } 之后,就是如何使用UsbDevice类了。

USB设备属于热插拔设备,一旦系统监测到其热插拔时间,会有相应事件上报:

[java]view plain copyframeworks/base/core/java/android/hardware/usb/UsbManager.java /** *ThisintentissentwhenaUSBdeviceisattachedtotheUSBbuswheninhostmode. */ publicstaticfinalStringACTION_USB_DEVICE_ATTACHED= "android.hardware.usb.action.USB_DEVICE_ATTACHED"; /** *ThisintentissentwhenaUSBdeviceisdetachedfromtheUSBbuswheninhostmode. */ publicstaticfinalStringACTION_USB_DEVICE_DETACHED= "android.hardware.usb.action.USB_DEVICE_DETACHED"; 所以,注册监听事件的广播即可,如:

[java]view plain copyclassUsbDeviceEventReceiverextendsBroadcastReceiver{ @Override publicvoidonReceive(Contextcontext,Intentintent){ UsbDevicedevice=(UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); } } mReceiver=newUsbDeviceEventReceiver(); IntentFilterfilter=newIntentFilter(); filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); registerReceiver(mReceiver,filter);

六、结束

Android流程:driver->HAL->Framework->APP,几乎所有模块都是这个模式,对于一个外设,如果这几个部分都清楚的话心里会特别明亮。

转载至/rodulf/article/details/51916998

如果觉得《获取usb设备类型》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。