Android USB 開發詳解

來源:互聯網
上載者:User

標籤:else   對象   lse   byte   產品   模式   equal   and   沒有   

Android USB 開發詳解

先附上 Android USB 官方文檔

Android通過兩種模式支援各種 USB 外設和 Android USB 附件(實現Android附件協議的硬體):USB附件和USB主機。USB開發需 Android 3.1(API層級12)以上。由於本人工作中只用到了主機模式,所以本文的側重點在主機模式開發。

  • Android USB 開發詳解
    • 調試
    • 一、AndroidManifest 檔案設定
    • 二、USB 裝置的串連和使用
      • 1.Android 中的 USB
      • 2.USB 裝置的插入
      • 3.擷取 UsbManager
      • 4.擷取 USB 裝置列表
      • 5.擷取特定的裝置
      • 6.申請 USB 裝置使用許可權
      • 7.通訊
    • 其他
調試

在使用 USB 串連裝置調試的時候,USB 外設將不能串連至裝置,可以使用 WIFI 的方式串連調試,settings -> plugin -> WiFi ADB 外掛程式好幾個,選個適合自己的就 OK。

或者…我這裡正好有一篇Android 模擬器串連 USB 裝置喜歡點個贊哈!

一、AndroidManifest 檔案設定
  • uses-feature 申明這個軟體需要使用 USB 功能,申明這個 Google Play 會把不滿足的裝置過濾掉,一般用 USB 的都是定製開發,忽略就行
<uses-feature android:name="android.hardware.usb.host"/>
  • 1
  • 將應用程式的最低SDK設定為API層級12或更高,早期 API 沒有。
  • 如果你希望你的應用程式串連指定的 USB 裝置時被通知,需指定 和 元素對用於 android.hardware.usb.action.USB_DEVICE_ATTACHED。該 元素指向聲明識別有關您要檢測的裝置資訊的外部XML資源檔。
<activity            android:name=".MainActivity"            android:screenOrientation="landscape">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <!-- 如果這裡是啟動 Activity 的話,點擊 USB 接入的彈窗會啟動該頁面 -->                <category android:name="android.intent.category.LAUNCHER" />                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />            </intent-filter>            <meta-data                android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"                android:resource="@xml/device_filter" />        </activity>
  • 在XML資源檔中,聲明要過濾的USB裝置的元素。以下列表描述了屬性 。通常,如果要過濾特定裝置並使用類,子類和協議(如果要過濾一組USB裝置(如大量儲存裝置或數位相機)),請使用供應商(vendor-id)和產品(product-id)ID,在開發中這些過濾ID一般可以在文檔中找到,或者自己連上看也行。你可以指定部分或全部這些屬性。
    將資源檔儲存在res/xml/目錄中。資源檔名(不帶.xml副檔名)必須與您在元素中指定的檔案名稱相同 。對於XML資源檔格式的 例子如下:
<?xml version="1.0" encoding="utf-8"?><resources>    <usb-device        class="255"        product-id="5678"        protocol="1 "        subclass="66"        vendor-id="1234" /></resources>

 

配置好資訊清單檔後當使用者串連與您的裝置過濾器匹配的裝置時,系統會向他們顯示一個對話方塊,詢問他們是否要啟動您的應用程式。如果使用者接受,則應用程式將自動具有訪問裝置的許可權,直到裝置中斷連線。如果給了預設,那麼這個 USB 裝置插入後會自動啟動這個 Activity

二、USB 裝置的串連和使用

在資訊清單檔中配置好以後我們直接進入 Java 代碼環節

1.Android 中的 USB

Android 3.1(API層級12)以上原生提供了 USB 開發的 API,在android.hardware.usb包下提供了開發的相關類。

Class 說明
UsbManager 獲得 USB 管理器,與串連的 USB 裝置通訊。
UsbDevice USB 裝置的抽象,每個UsbDevice 都代表一個 USB 裝置。
UsbInterface 定義了裝置的功能集,一個 UsbDevice 可能包含一個或多個UsbInterface,每個 Interface 都是獨立的。
UsbEndpoint UsbEndpoint 是 interface 的通訊通道。
UsbDeviceConnection host 與 device 建立的串連,並在 endpoint 傳輸資料。
UsbRequest USB 請求包。
UsbConstants USB 常量的定義
2.USB 裝置的插入

Android 系統中,USB 裝置的插入和拔出是以系統廣播的形式發送的,我們只要註冊監聽這個廣播就好

public class USBReceiver extends BroadcastReceiver {    public static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";    @Override    public void onReceive(Context context, Intent intent) {        String action = intent.getAction();        if (ACTION_USB_PERMISSION.equals(action)) {            // 擷取許可權結果的廣播            synchronized (this) {                UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);                if (device != null) {                    //call method to set up device communication                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {                        Log.e("USBReceiver", "擷取許可權成功:" + device.getDeviceName());                    } else {                        Log.e("USBReceiver", "擷取許可權失敗:" + device.getDeviceName());                    }                }            }        }else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {            // 有新的裝置插入了,在這裡一般會判斷這個裝置是不是我們想要的,是的話就去請求許可權        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {            // 有裝置拔出了        }    }}

 

3.擷取 UsbManager
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
4.擷取 USB 裝置列表
    public List<UsbDevice> getDeviceList() {        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();        List<UsbDevice> usbDevices = new ArrayList<>();        while (deviceIterator.hasNext()) {            UsbDevice device = deviceIterator.next();            usbDevices.add(device);            Log.e("USBUtil", "getDeviceList: " + device.getDeviceName());        }        return usbDevices;    }

 

5.擷取特定的裝置
    /**     * mVendorId=1137,mProductId=85  佳博 3150T 標籤印表機     *     * @param vendorId  廠商ID     * @param productId 產品ID     * @return  device     */    public UsbDevice getUsbDevice(int vendorId, int productId) {        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();        while (deviceIterator.hasNext()) {            UsbDevice device = deviceIterator.next();            if (device.getVendorId() == vendorId && device.getProductId() == productId) {                Log.e("USBUtil", "getDeviceList: " + device.getDeviceName());                return device;            }        }        Toast.makeText(context, "沒有對應的裝置", Toast.LENGTH_SHORT).show();        return null;    }
6.申請 USB 裝置使用許可權

安卓系統對 USB 裝置的使用需要得到相應的許可權,這個許可權要使用者手動授予,或插入裝置時應用到你的應用中。在使用 USB 裝置前首先我們要確認一下上一節中的device是否已經獲得許可權,如果沒有就要主動申請許可權:

    /**     * 判斷對應 USB 裝置是否有許可權     */    public boolean hasPermission(UsbDevice device) {        return usbManager.hasPermission(device);    }    /**     * 請求擷取指定 USB 裝置的許可權     */    public void requestPermission(UsbDevice device) {        if (device != null) {            if (usbManager.hasPermission(device)) {                Toast.makeText(context, "已經擷取到許可權", Toast.LENGTH_SHORT).show();            } else {                if (mPermissionIntent != null) {                    usbManager.requestPermission(device, mPermissionIntent);                    Toast.makeText(context, "請求USB許可權", Toast.LENGTH_SHORT).show();                } else {                    Toast.makeText(context, "請註冊USB廣播", Toast.LENGTH_LONG).show();                }            }        }    }

 

註冊廣播:

    public void registerReceiver(Activity context) {        mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);        context.registerReceiver(usbReceiver, filter);    }

 

7.通訊

與 USB 裝置的通訊可以是同步的也可以是非同步。無論哪種情況,你都應該建立一個新線程來執行所有資料轉送,避免阻塞UI線程。

第一步,開啟通訊連接埠

    public boolean openPort(UsbDevice device) {        //擷取裝置介面,一般只有一個,多個的自己研究去        usbInterface = device.getInterface(0);        // 判斷是否有許可權        if (hasPermission(device)) {            // 開啟裝置,擷取 UsbDeviceConnection 對象,串連裝置,用於後面的通訊            usbConnection = usbManager.openDevice(device);            if (usbConnection == null) {                return false;            }            if (usbConnection.claimInterface(usbInterface, true)) {                Toast.makeText(Utils.getContext(), "找到 USB 裝置介面", Toast.LENGTH_SHORT).show();            } else {                usbConnection.close();                Toast.makeText(Utils.getContext(), "沒有找到 USB 裝置介面", Toast.LENGTH_SHORT).show();                return false;            }        } else {            Toast.makeText(Utils.getContext(), "沒有 USB 許可權", Toast.LENGTH_SHORT).show();            return false;        }        //擷取介面上的兩個端點,分別對應 OUT 和 IN        for (int i = 0; i < usbInterface.getEndpointCount(); ++i) {            UsbEndpoint end = usbInterface.getEndpoint(i);            if (end.getDirection() == UsbConstants.USB_DIR_IN) {                usbEndpointIn = end;            } else {                usbEndpointOut = end;            }        }        return true;    }

 

第二步,發送資料

usbConnection.bulkTransfer(usbEndpointOut, bytes, bytes.length, 500);
其他

剩餘的 API 我會在項目不斷完善的同時更新上來

附:demo 傳送門

Android USB 開發詳解

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.