分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow
项目中需要区分USB的连接设备是打印机还是电子秤,然后上网搜索到了一篇博客,根据这个博客写的一个小的例子:非常感谢hao2014_的这篇博客http://blog.csdn.net/u013686019/article/details/50409421
MainActivity:
package com.example.administrator.usbmanagertest;import android.content.Context;import android.hardware.usb.UsbDevice;import android.hardware.usb.UsbInterface;import android.hardware.usb.UsbManager;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.TextView;import java.util.HashMap;import java.util.Iterator;public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.sb); } public void showUsbList(View view) { UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); StringBuilder sb = new StringBuilder(); while (deviceIterator.hasNext()){ UsbDevice usbDevice = 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"); int deviceClass = usbDevice.getDeviceClass(); if(deviceClass==0) { UsbInterface anInterface = usbDevice.getInterface(0); int interfaceClass = anInterface.getInterfaceClass(); sb.append("device Class 为0-------------\n"); sb.append("Interface.describeContents()="+anInterface.describeContents()+"\n"); sb.append("Interface.getEndpointCount()="+anInterface.getEndpointCount()+"\n"); sb.append("Interface.getId()="+anInterface.getId()+"\n"); //http://blog.csdn.net/u013686019/article/details/50409421 //http://www.usb.org/developers/defined_class/#BaseClassFFh //通过下面的InterfaceClass 来判断到底是哪一种的,例如7就是打印机,8就是usb的U盘 sb.append("Interface.getInterfaceClass()="+anInterface.getInterfaceClass()+"\n"); if(anInterface.getInterfaceClass()==7){ sb.append("此设备是打印机\n"); }else if(anInterface.getInterfaceClass()==8){ sb.append("此设备是U盘\n"); } sb.append("anInterface.getInterfaceProtocol()="+anInterface.getInterfaceProtocol()+"\n"); sb.append("anInterface.getInterfaceSubclass()="+anInterface.getInterfaceSubclass()+"\n"); sb.append("device Class 为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
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/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="Show USB List" /> <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>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
参考博客地址:
http://blog.csdn.net/u013686019/article/details/50409421
一、问题
现在有USB设备插入Android系统,那么如何得知插入的设备类型?是USB打印机,U盘,还是USB鼠标?
二、USB类型规定
对于USB类型,USB组织是有规定的,见:http://www.usb.org/
比如:
Base Class |
Descriptor Usage |
Description |
00h |
Device |
|
01h |
Interface |
|
02h |
Both |
|
03h |
Interface |
|
05h |
Interface |
|
06h |
Interface |
|
07h |
Interface |
三、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));
Base Class |
Descriptor Usage |
Description |
00h |
Device |
就在第二个结构体usb_interface_descriptor中:
- include/uapi/linux/usb/ch9.h
- struct usb_interface_descriptor {
- __u8 bInterfaceClass;
- __u8 bInterfaceSubClass;
- __u8 bInterfaceProtocol;
- } __attribute__ ((packed));
比如,对于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_INTERFACE 0 /* for DeviceClass */
- #define USB_CLASS_AUDIO 1
- #define USB_CLASS_COMM 2
- #define USB_CLASS_HID 3
- #define USB_CLASS_PHYSICAL 5
- #define USB_CLASS_STILL_IMAGE 6
- #define USB_CLASS_PRINTER 7
- #define USB_CLASS_MASS_STORAGE 8
- #define USB_CLASS_HUB 9
- #define USB_CLASS_CDC_DATA 0x0a
- #define USB_CLASS_CSCID 0x0b /* chip+ smart card */
- #define USB_CLASS_CONTENT_SEC 0x0d /* content security */
- #define USB_CLASS_VIDEO 0x0e
- #define USB_CLASS_WIRELESS_CONTROLLER 0xe0
- #define USB_CLASS_MISC 0xef
- #define USB_CLASS_APP_SPEC 0xfe
- #define USB_CLASS_VENDOR_SPEC 0xff
- drivers/usb/gadget/printer.c
- static 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
- };
四、HAL层和Framework层
HAL层的usbhost.c文件为我们获取Linux driver中USB设备的信息提供了便利,除了USB设备类型,还可以得到USB设备的厂商名称、产品名称、***等:
system/core/libusbhost/usbhost.c
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.java
- public class UsbInterface implements Parcelable {
- private final int mId;
- private final int mClass;
- private final int mSubclass;
- private final int mProtocol;
- private final Parcelable[] mEndpoints;
- }
- frameworks/base/core/java/android/hardware/usb/UsbDevice.java
- public 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;
- }
- 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.java
- public 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];
- }
- }
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 {
- @Override
- public 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->HAL->Framework->APP,几乎所有模块都是这个模式,对于一个外设,如果这几个部分都清楚的话心里会特别明亮。
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow