Android USB Host與HID通訊


前端時間搗鼓一個HID的硬件, 需要和android通信, 網上搜索了一圈,收獲不小.

比較好的文章是: 
     Android USB Host與HID通訊

     Android Service創建USB HOST通信

其中代碼之處有些地方需要注意的, 特此注明一下:

/**
 * USB HOST 連接 HID
 * @author IVAN
 *
 */
public class MainActivity extends Activity {
    private static final String TAG = "USB_HOST";
 
    private UsbManager myUsbManager;
    private UsbDevice myUsbDevice;
    private UsbInterface myInterface;
    private UsbDeviceConnection myDeviceConnection;
 
    private final int VendorID = 8457;    //這里要改成自己的硬件ID private final int ProductID = 30264;
 
    private TextView info;
 
    private UsbEndpoint epOut;
    private UsbEndpoint epIn;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        info = (TextView) findViewById(R.id.info);
 
        // 獲取UsbManager
        myUsbManager = (UsbManager) getSystemService(USB_SERVICE);
 
        enumerateDevice();
 
        findInterface();
 
        openDevice();
 
        assignEndpoint();
 
    }
 
    /**
     * 分配端點,IN | OUT,即輸入輸出;此處我直接用1為OUT端點,0為IN,當然你也可以通過判斷
     */

     //USB_ENDPOINT_XFER_BULK
     /*
     #define USB_ENDPOINT_XFER_CONTROL 0 --控制傳輸
     #define USB_ENDPOINT_XFER_ISOC 1 --等時傳輸
     #define USB_ENDPOINT_XFER_BULK 2 --塊傳輸
     #define USB_ENDPOINT_XFER_INT 3 --中斷傳輸
     * */

    private void assignEndpoint() {

          if (myInterface != null) { //這一句不加的話 很容易報錯  導致很多人在各大論壇問:為什么報錯呀 

              //這里的代碼替換了一下 按自己硬件屬性判斷吧

             for (int i = 0; i < myInterface.getEndpointCount(); i++) { 

                UsbEndpoint ep = myInterface.getEndpoint(i);

                if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
                if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                   epOut = ep;

                 } else { 

                  epIn = ep;

                  }
                }
              }
           }

 Log.d(TAG, getString(R.string.text)); } /** * 打開設備 */
    private void openDevice() { if (myInterface != null) { UsbDeviceConnection conn = null; // 在open前判斷是否有連接權限;對於連接權限可以靜態分配,也可以動態分配權限,可以查閱相關資料
            if (myUsbManager.hasPermission(myUsbDevice)) { conn = myUsbManager.openDevice(myUsbDevice); } if (conn == null) { return; } if (conn.claimInterface(myInterface, true)) { myDeviceConnection = conn; // 到此你的android設備已經連上HID設備
                Log.d(TAG, "打開設備成功"); } else { conn.close(); } } } /** * 找設備接口 */
    private void findInterface() { if (myUsbDevice != null) { Log.d(TAG, "interfaceCounts : " + myUsbDevice.getInterfaceCount()); for (int i = 0; i < myUsbDevice.getInterfaceCount(); i++) { UsbInterface intf = myUsbDevice.getInterface(i); // 根據手上的設備做一些判斷,其實這些信息都可以在枚舉到設備時打印出來
                if (intf.getInterfaceClass() == 8
                        && intf.getInterfaceSubclass() == 6
                        && intf.getInterfaceProtocol() == 80) { myInterface = intf; Log.d(TAG, "找到我的設備接口"); } break; } } } /** * 枚舉設備 */
    private void enumerateDevice() { if (myUsbManager == null) return; HashMap<String, UsbDevice> deviceList = myUsbManager.getDeviceList(); if (!deviceList.isEmpty()) { // deviceList不為空
            StringBuffer sb = new StringBuffer(); for (UsbDevice device : deviceList.values()) { sb.append(device.toString()); sb.append("\n"); info.setText(sb); // 輸出設備信息
                Log.d(TAG, "DeviceInfo: " + device.getVendorId() + " , "
                        + device.getProductId()); // 枚舉到設備
                if (device.getVendorId() == VendorID && device.getProductId() == ProductID) { myUsbDevice = device; Log.d(TAG, "枚舉設備成功"); } } } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }

獲取數據的代碼:

 ncount = myDeviceConnection.bulkTransfer(epIn, buffer, buffer.length,  
                            100);

這里注意數據讀取的長度, 這個對某些硬件來說非常重要,  有的硬件小了或者大了立馬死機重啟, 要么就是一直返回-1

這個數據的長度需要根據硬件屬性來,

    有一種辦法是通過int inMax = epIn.getMaxPacketSize()來獲取;

    還有一種辦法是通過windows下面的hid程序探測設備的數據長度;

 

至於讀不到硬件的問題 我覺得以下辦法不會有幫助了, 要么是硬件不支持, android4.0以上 貌似都包含了以下的文件信息了

將android.hardware.usb.host.xml文件放到/system/etc/permissions下;第二處是在同目錄下的handheld_core_hardware.xml里面添加一句<feature name="android.hardware.usb.host">


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM