Android USB Host與HID通訊

來源:互聯網
上載者:User

標籤:

前端時間搗鼓一個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">

Android USB Host與HID通訊

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.