Android USB 开发详解
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 的都是定制開發,忽略就行
- 1
- 將應用程序的最低SDK設置為API級別12或更高,早期 API 沒有。
- 如果你希望你的應用程序連接指定的 USB 設備時被通知,需指定 和 元素對用于 android.hardware.usb.action.USB_DEVICE_ATTACHED。該 元素指向聲明識別有關您要檢測的設備信息的外部XML資源文件。
- 在XML資源文件中,聲明要過濾的USB設備的元素。以下列表描述了屬性 。通常,如果要過濾特定設備并使用類,子類和協議(如果要過濾一組USB設備(如大容量存儲設備或數碼相機)),請使用供應商(vendor-id)和產品(product-id)ID,在開發中這些過濾ID一般可以在文檔中找到,或者自己連上看也行。你可以指定部分或全部這些屬性。?
將資源文件保存在res/xml/目錄中。資源文件名(不帶.xml擴展名)必須與您在元素中指定的文件名相同 。對于XML資源文件格式的 例子如下:
?
配置好清單文件后當用戶連接與您的設備過濾器匹配的設備時,系統會向他們顯示一個對話框,詢問他們是否要啟動您的應用程序。如果用戶接受,則應用程序將自動具有訪問設備的權限,直到設備斷開連接。如果給了默認,那么這個 USB 設備插入后會自動啟動這個 Activity
二、USB 設備的連接和使用
在清單文件中配置好以后我們直接進入 Java 代碼環節
1.Android 中的 USB
Android 3.1(API級別12)以上原生提供了 USB 開發的 API,在android.hardware.usb包下提供了開發的相關類。
| 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";@Overridepublic 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 communicationif (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 和 INfor (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 我會在項目不斷完善的同時更新上來
總結
以上是生活随笔為你收集整理的Android USB 开发详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高效程序员
- 下一篇: Android USB串口开发