Android 获取USB设备的类型
来源:互联网 发布:映射网络驱动器 编辑:程序博客网 时间:2024/04/27 19:39
Version info:Linux: 3.10Android: 4.4.2
一、问题
现在有USB设备插入Android系统,那么如何得知插入的设备类型?是USB打印机,U盘,还是USB鼠标?
二、USB类型规定
对于USB类型,USB组织是有规定的,见:http://www.usb.org/
比如:
Base Class
Descriptor Usage
Description
00h
Device
Use class information in the Interface Descriptors
01h
Interface
Audio
02h
Both
Communications and CDC Control
03h
Interface
HID (Human Interface Device)
05h
Interface
Physical
06h
Interface
Image
07h
Interface
Printer
三、Linux对USB设备类型定义
在kernel中,有两个结构体的相关成员表征USB设备的类型,第一个usb_device_descriptor:
include/uapi/linux/usb/ch9.h/* USB_DT_DEVICE: Device descriptor */struct usb_device_descriptor {__u8 bDeviceClass;__u8 bDeviceSubClass;__u8 bDeviceProtocol;} __attribute__ ((packed));bDeviceClass成员值区别不同的USB设备,如果该值为0呢?看上边:
Base Class
Descriptor Usage
Description
00h
Device
Use class information in the Interface Descriptors
就在第二个结构体usb_interface_descriptor中:
include/uapi/linux/usb/ch9.hstruct usb_interface_descriptor {__u8 bInterfaceClass;__u8 bInterfaceSubClass;__u8 bInterfaceProtocol;} __attribute__ ((packed));bInterfaceClass成员即是。
比如,对于USB打印机设备,定义如下:
include/uapi/linux/usb/ch9.h/* * Device and/or Interface Class codes * as found in bDeviceClass or bInterfaceClass * and defined by www.usb.org documents */#define USB_CLASS_PER_INTERFACE0/* for DeviceClass */#define USB_CLASS_AUDIO1#define USB_CLASS_COMM2#define USB_CLASS_HID3#define USB_CLASS_PHYSICAL5#define USB_CLASS_STILL_IMAGE6#define USB_CLASS_PRINTER7#define USB_CLASS_MASS_STORAGE8#define USB_CLASS_HUB9#define USB_CLASS_CDC_DATA0x0a#define USB_CLASS_CSCID0x0b/* chip+ smart card */#define USB_CLASS_CONTENT_SEC0x0d/* content security */#define USB_CLASS_VIDEO0x0e#define USB_CLASS_WIRELESS_CONTROLLER0xe0#define USB_CLASS_MISC0xef#define USB_CLASS_APP_SPEC0xfe#define USB_CLASS_VENDOR_SPEC0xffdrivers/usb/gadget/printer.cstatic struct usb_interface_descriptor intf_desc = {.bLength =sizeof intf_desc,.bDescriptorType =USB_DT_INTERFACE,.bNumEndpoints =2,.bInterfaceClass =USB_CLASS_PRINTER,.bInterfaceSubClass =1,/* Printer Sub-Class */.bInterfaceProtocol =2,/* Bi-Directional */.iInterface =0};对上了,不是?!
四、JNI和Framework层
JNI层的usbhost.c文件为我们获取Linux driver中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类获取信息
frameworks/base/core/java/android/hardware/usb/UsbInterface.javapublic class UsbInterface implements Parcelable { private final int mId; private final int mClass; private final int mSubclass; private final int mProtocol; private final Parcelable[] mEndpoints;}3、获取的信息另一部分通过调用UsbHostManager.java中的usbDeviceAdded()方法,把信息写到UsbDevice.java中,APP部分调用UsbDevice类获取信息
frameworks/base/core/java/android/hardware/usb/UsbDevice.javapublic class UsbDevice implements Parcelable { private final String mName; private final int mVendorId; private final int mProductId; private final int mClass; private final int mSubclass; private final int mProtocol; private final Parcelable[] mInterfaces;}接下来,我们就看下如此关键的usbDeviceAdded()方法:
frameworks/base/services/java/com/android/server/usb/UsbHostManager.java/* Called from JNI in monitorUsbHostBus() to report new USB devices */private void usbDeviceAdded(String deviceName, int vendorID, int productID,int deviceClass, int deviceSubclass, int deviceProtocol,/* array of quintuples containing id, class, subclass, protocol and number of endpoints for each interface */int[] interfaceValues, /* array of quadruples containing address, attributes, max packet size and interval for each endpoint */int[] endpointValues) {synchronized (mLock) {for (intf = 0; intf < numInterfaces; intf++) {int interfaceId = interfaceValues[ival++];int interfaceClass = interfaceValues[ival++];int interfaceSubclass = interfaceValues[ival++];int interfaceProtocol = interfaceValues[ival++];int numEndpoints = interfaceValues[ival++];interfaces[intf] = new UsbInterface(interfaceId, interfaceClass,interfaceSubclass, interfaceProtocol, endpoints);}UsbDevice device = new UsbDevice(deviceName, vendorID, productID,deviceClass, deviceSubclass, deviceProtocol, interfaces);mDevices.put(deviceName, device);}}
五、APP层
经过上面分析,获取USB设备类型等信息,已经心有成竹了,使用UsbDevice、UsbInterface两个类即可。其中,UsbInterface类是包含在UsbDevice类中的:frameworks/base/core/java/android/hardware/usb/UsbDevice.javapublic class UsbDevice implements Parcelable { private final Parcelable[] mInterfaces;/** * Returns the {@link UsbInterface} at the given index. * * @return the interface */ public UsbInterface getInterface(int index) { return (UsbInterface)mInterfaces[index]; }}之后,就是如何使用UsbDevice类了。
USB设备属于热插拔设备,一旦系统监测到其热插拔时间,会有相应事件上报:
frameworks/base/core/java/android/hardware/usb/UsbManager.java/** * This intent is sent when a USB device is attached to the USB bus when in host mode. */public static final String ACTION_USB_DEVICE_ATTACHED ="android.hardware.usb.action.USB_DEVICE_ATTACHED";/** * This intent is sent when a USB device is detached from the USB bus when in host mode. */public static final String ACTION_USB_DEVICE_DETACHED ="android.hardware.usb.action.USB_DEVICE_DETACHED";所以,注册监听事件的广播即可,如:
class UsbDeviceEventReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);}}mReceiver = new UsbDeviceEventReceiver();IntentFilter filter = new IntentFilter();filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);registerReceiver(mReceiver, filter);
六、结束
Android流程:driver->JNI->Framework->APP,几乎所有模块都是这个模式,对于一个外设,如果这几个部分都清楚的话心里会特别明亮。
- Android 获取USB设备的类型
- 获取usb设备类型
- 使用android USB API 无法获取USB设备的解决方法
- 获取设备类型 android
- 获取USB设备的信息
- Android 获取外置SDCard USB等设备
- Android 获取蓝牙设备类型
- Android设备的USB通讯
- 如何判断USB设备的类型
- USB设备类型代码
- USB设备类型
- USB设备类型码
- 如何获取USB设备的序列号?
- VC 获取USB设备的ID号
- 获取usb设备的vid,pid
- 获取IOS的设备类型
- 获取usb设备
- android 3.0以上对usb设备的访问USB
- http post 请求(下)
- Tips:使用Xcode查找项目中的中文字符串
- 图 之 MST(最小生成树 — kruskal算法 )并查集实现
- Codeforces Round #336 (Div. 2) B. Hamming Distance Sum
- phonegap安装 环境搭建与配置详解( 完整版 提供下载地址)
- Android 获取USB设备的类型
- Android MVP模式的应用
- http post请求(上)
- 库(lib)与jar包有什么区别啊?
- Android错误集锦
- 程序员如何做到『编程速度又快,Bug 数量又少』?
- PSExec中遇到的几个问题及其解决方法
- Android 仿QQ界面的实现
- andriod-x86 移植项目---获取源码