硬件交互的首篇對設備硬件的分類中,互聯通信系列硬件主要用來與其他設備進行數據交互。從本文開始,將重點介紹該系列相關硬件。

互聯通信系列硬件

根據硬件的可通信距離,由近及遠分為USB、NFC、藍牙、WLAN,SIM卡槽,這些硬件之間的功能原理及關系可以查找其他資料詳細學習。總之,他們為當前設備與其他設備的交互搭建了橋梁,只要雙方設備均遵循該系列硬件的協議,就可以在硬件層互相通信,而設備上的Android操作系統便會將硬件層的數據轉換為應用層數據,進而與應用程序交互。這樣也就實現了兩個不同設備上的應用程序間的交互方案。理論上這個方案是可行的,那實際各硬件的使用方式分別是怎麼樣的呢?

USB接口

在應用程序中與USB硬件的交互,系統提供了兩種方式,包括將該應用程序所在設備的USB接口作為主機模式,和該應用程序所在設備的USB接口作為配件模式。在主機模式下,該應用程序所在設備通過USB接口為其他接入的USB設備供電,通常連接沒有自帶電源的設備(比如U盤)時啟用此種模式;反之在配件模式下,是該應用程序所在設備接收通過USB接口接入的其他USB設備的電源提供,通常在連接有電源的設備(比如筆記本電腦)時啟用此模式。理論上這兩種模式只是針對USB硬件的供電方不同而區分,均可以在USB接口連接的兩個設備之間的數據傳輸。

主機模式

權限聲明

在應用程序的清單文件中,需要聲明<uses-feature />標簽,並設置其屬性android:name值為"android.hardware.usb.host"。該標簽設置並不是通過應用程序向系統申請權限,而是聲明應用程序需要使用USB主機模式。

使用流程
獲取USB主機設備

主機模式下,其中一種常用情况,應用程序可以監聽插入USB接口的設備,此時可以在需要監聽的界面Activity對應的清單文件注册信息中增加指定的接收意圖,意圖值為android.hardware.usb.action.USB_DEVICE_ATTACHED。這樣在USB設備接入後,系統會發送上述意圖值的廣播,從而啟動當前界面Activity

在啟動後的界面Activity中,可以調用getIntent().getParcelableExtra(UsbManager.EXTRA_DEVICE)系列方法,獲取android.hardware.usb.UsbDevice USB設備類的對象。

主機模式下另外一種情况,是直接獲取已連接的USB設備。在能獲取上下文環境Context對象的地方,調用該對象的getSystemService(String name),並指定參數值 nameContext.USB_SERVICE="usb",獲得android.hardware.usb.UsbManagerUSB管理類的對象。調用該對象的getDeviceList()方法,返回List<UsbDevice>,同樣能獲取到當前設備連接的所有USB硬件對象的列錶數據。

在直接獲取已連接USB設備的情况下,應用程序需要主動向用戶申請設備通信權限。通過USBManager設備管理類對象的requestPermission(UsbAccessory accessory, PendingIntent pi)方法,在用戶同意授權後,才能繼續後續設備通信操作。

USB設備通信

在拿到UsbDevice類型的USB設備類對象,和UsbManager管理類對象之後,調用USB管理類對象的openDevice(UsbDevice device)方法,得到android.hardware.usb.UsbDeviceConnection USB設備連接對象,其參數 device 便是要通信的USB設備對象。

建立UsbDeviceConnection設備連接對象後,通信過程中還需要分別借助android.hardware.usb.UsbInterface USB接口類和android.hardware.usb.UsbEndpoint USB端點類。

在獲取UsbDevice類型的設備類對象後,調用其getInterface(int index)方法獲取UsbInterfaceUSB接口類對象,其中參數 index 是當前USB設備可獲取的所有接口數量中的索引值,而獲取UsbDevice的所有接口數量,可根據另外一個方法getInterfaceCount()查看。

在獲取UsbInterface類型的接口對象後,調用其getEndpoint(int index)方法獲取UsbEndpointUSB端點類對象,其中參數 index 是當前USB接口中可獲取的所有斷點數量中的索引值,而獲取UsbInterface的所有斷點數量,可根據另外一個方法getEndpointCount()查看。

通過梅開二度獲取USB接口對象和USB端點對象之後,首先要占用USB設備資源。繼續調用UsbDeviceConnection連接對象的claimInterface(UsbInterface intf, boolean force)方法,其中參數 intf 便是上文獲取UsbInterface接口類對象,參數 force 標明是否强制占用。返回boolean類型的結果錶示占用是否成功。

在占用USB設備資源之後,就可以接收USB設備的通信數據了。調用UsbDeviceConnection連接對象的bulkTransfer (UsbEndpoint endpoint, byte[] buffer, int offset, int length, int timeout)方法。參數 endpoint 便是上文獲取UsbEndpoint端點類對象;參數 buffer 用以存儲通信中的二進制數組;參數 offset 可選項,默認值為0,用以標記存放數組 buffer 的起始比特置;參數 length 用以標記存放數組的長度;參數 timeout 作為通信連接的最大時長。返回通信過程中實際傳輸的數據長度。

通信結束後,只需要關閉連接並釋放占用的設備資源。調用UsbDeviceConnection連接對象的close()方法可以關閉通信連接。而調用該對象的releaseInterface(UsbInterface intf)方法可以釋放占用的UsbInterface設備接口類型的參數 intf 對象。

配件模式

權限聲明

在應用程序的清單文件中,需要聲明<uses-feature />標簽,並設置其屬性android:name值為"android.hardware.usb.accessory"。該標簽設置並不是通過應用程序向系統申請權限,而是聲明應用程序需要使用USB配件模式。

使用流程
獲取USB配件

配件模式下,其中一種常用情况,應用程序可以監聽插入USB接口的設備,此時可以在需要監聽的界面Activity對應的清單文件注册信息中增加指定的接收意圖,意圖值為android.hardware.usb.action.USB_ACCESSORY_ATTACHED。這樣在USB設備接入後,系統會發送上述意圖值的廣播,從而啟動當前界面Activity

在啟動後的界面Activity中,可以調用getIntent().getParcelableExtra(UsbManager.EXTRA_ACCESSORY)系列方法,獲取android.hardware.usb.UsbAccessory USB配件類的對象。

同樣在配件模式下另外一種情况,是直接獲取已連接的USB配件。在能獲取上下文環境Context對象的地方,調用該對象的getSystemService(String name),並指定參數值 nameContext.USB_SERVICE="usb",獲得android.hardware.usb.UsbManagerUSB管理類的對象。調用該對象的getAccessoryList()方法,返回List<UsbAccessory>,同樣能獲取到當前設備連接的所有USB配件對象的列錶數據。

與主機模式類似,在直接獲取已連接USB配件的情况下,應用程序需要主動向用戶申請設備通信權限。通過USBManager設備管理類對象的requestPermission(UsbAccessory accessory, PendingIntent pi)方法,在用戶同意授權後,才能繼續後續設備通信操作。

USB設備通信

在拿到UsbAccessory類型的USB配件類對象,和UsbManager管理類對象之後,調用USB管理類對象的openAccessory(UsbAccessory accessory)方法,得到android.os.ParcelFileDescriptor 數據流化的文件描述符類的對象,其參數 accessory 便是要通信的USB配件對象。

在獲取ParcelFileDescriptor數據流化的文件描述符類的對象後,調用其getFileDescriptor()方法得到java.io.FileDescriptor普通的文件描述符類型的對象,之後通過該對象創建基本的文件輸入流java.io.FileInputStream對象以讀取USB配件中的數據,或者創建基本的文件輸出流java.io.FileOutputStream對象以將數據寫入USB配件中。

通信結束後,只需要關閉數據流化的文件描述符的占用即可。通過調用ParcelFileDescriptor對象的close()方法以實現該操作。

主機模式與配件模式的區別

代碼軟件層

主機模式下,主要使用UsbDevice類,可以獲取所連接USB設備的詳細信息。

配件模式下,只能使用UsbAccessory類,只能獲取連接USB設備的基本信息。

硬件層

主機模式下,由應用程序所在的設備向主線供電,並向連接的USB設備供電。

配件模式下,由連接的USB設備作為主機向主線供電,並向應用程序所在的設備供電。

Android系統編程入門系列之硬件交互——通信硬件USB的更多相關文章

  1. Android系統編程入門系列之加載界面Activity

    上回說到應用初始化加載及其生命周期,在Android系統調用Applicaiton.onCreate()之後,繼續創建並加載清單文件中注册的首個界面即主Activity,也可稱之為入口界面.主Acti ...

  2. Android系統編程入門系列之硬件交互——多媒體攝像頭

    多媒體系列硬件 多媒體包括圖片.動畫.音頻.視頻,這些多媒體素材的采集(輸入)主要依靠攝像頭和麥克風等硬件設備轉化為基礎數據,而他們的播放渲染(輸出),則需要依靠具有相關功能的編解碼軟件.當然隨著硬件 ...

  3. Android系統編程入門系列之硬件交互——傳感器

    到目前為止,關於應用程序與用戶之間的相關內容便比較膚淺的大致介紹完畢.而在整個系統架構中,應用程序與用戶之間的交互,猶如參天大樹上的枝幹和樹葉,交互起來五彩繽紛,但使整個生態系統保持生命力的核心,在於 ...

  4. Android系統編程入門系列之硬件交互——多媒體展示

    前兩篇文章通過麥克風硬件和攝像頭硬件分別采集音頻和視頻的多媒體數據,在得到的多媒體數據通常是以編碼文件的格式存儲,在用戶需要展示時,可通過設備的內置擴音器或藍牙耳機等硬件播放音頻,通過設備的顯示屏或外 ...

  5. Android系統編程入門系列之界面Activity交互響應

    在上篇文章中已經了解到界面Activity的繪制完全依賴其加載的視圖組件View,不僅如此,用戶的每次觸摸操作都可以在界面Activity內接收並響應,也可以直接傳遞給其中的某個視圖View響應.本文 ...

  6. Android系統編程入門系列之應用環境及開發環境介紹

    作為移動端操作系統,目前最新的Android 11.0已經發展的比較完善了,現在也到了系統的整理一番的時間,接下來的系列文章將以Android開發者為中心,爭取用歸納總結的態度對初級入門者所應 ...

  7. Android系統編程入門系列之服務Service齊頭並進多線程任務

    在上篇文章中初步了解了Android系統的四大組件之一的服務Service,在服務內可以執行無用戶交互的耗時操作任務,但是包括之前關於界面系列文章在內,生命周期方法都是在主線程內被系統回調的.如果直接 ...

  8. Android系統編程入門系列之界面Activity繪制展示

    上篇文章介紹了界面Activity的啟動方式和生命周期,本篇將繼續介紹在界面Activity中的內容是如何繪制展示給用戶的. 在Android系統上運行新創建的界面Activtiy,給用戶展示的是空白 ...

  9. Android系統編程入門系列之加載服務Service

    之前幾篇文章簡單梳理了在Android系統的四大組件之一,最主要的界面Activity中,使應用程序與用戶進行交互響應的相關知識點,那對於應用程序中不需要與用戶交互的邏輯,又要用到哪些內容呢?本文開始 ...

  10. Android系統編程入門系列之廣播接收者BroadcastReceiver實現進程間通信

    在前邊幾篇關於Android系統兩個重要組件的介紹中,界面Activity負責應用程序與用戶的交互,服務Service負責應用程序內部線程間的交互或兩個應用程序進程之間的數據交互.看上去這兩大組件就能 ...

隨機推薦

  1. String源碼中的&quot;avoid getfield opcode&quot;

    引言: 之前一篇文章梳理了String的不變性原則,還提到了一段源碼中注釋"avoid getfield opcode",當時通過查閱資料發現,這是為了防止 getfield(獲取 ...

  2. AcmeAir安裝AI探針--SaaS版

    一.安裝SaaS版AI探針准備工作: 1.准備好可用的docker版AcmeAir應用 2.在SaaS官網tpm.oneapm.com上已注册可用的賬號 3.登錄tpm.oneapm.com,點擊選擇 ...

  3. Xstream之常用方式與常用注解

    示例代碼 Blog teamBlog = new Blog(new Author("Guilherme Silveira")); teamBlog.add(new Entry(&q ...

  4. BZOJ 3110: [Zjoi2013]K大數查詢( 樹狀數組套主席樹 )

    BIT+(可持久化)權值線段樹, 用到了BIT的差分技巧. 時間複雜度O(Nlog^2(N)) ---------------------------------------------------- ...

  5. JavaScript中事件綁定的三種方式

    JavaScript使得網頁與用戶友好交互,在使用 js 進行時間綁定的時候有三種綁定方式. 第一種:初學者以及普通寫法 <div id="dom0"> <inp ...

  6. [ExtJS5學習筆記]第九節 Extjs5的mvc與mvvm框架結構簡介

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/38537431 本文作者:sushengmiyan ------------------ ...

  7. 推介一個學習JAVA的系列教程-狗魚IT教程

    介紹一個學JAVA的零基礎學習JAVA的網站,推介一個學習JAVA的系列教程-狗魚IT教程 下面是java的系教程: 1、[java教程]Java 教程 2、[java教程]Java 簡介 3、[ja ...

  8. lazy-init 懶加載的藝術

    懶加載是一種加載方式,加載單例對象一般有兩種方式,一是在啟動時就立即創建好,另一種則是在需要用到的時候再去加載即懶加載.懶加載一般會針對單例場景,且一般是針對在加載消耗較大費時,且不一定會用到的場景. ...

  9. git 一些常見問題 總結

    問題1: Auto packing the repository in background for optimum performance. See "git help gc" ...

  10. 數據庫SQL語言學習--上機練習4(視圖)

    上機練習4 一.實驗目的 . 熟悉和掌握對數據錶中視圖的查詢操作和 SQL 命令的使用: . 熟悉和掌握對數據錶中視圖的更新操作和 SQL 命令的使用,並注意視圖更新與基本錶更新的區別與聯系: . 學 ...