主頁 > 移動端開發 > Android系統編程入門系列之硬體互動——通信硬體Bluetooth

Android系統編程入門系列之硬體互動——通信硬體Bluetooth

2022-01-31 07:00:11 移動端開發

通信硬體NFC的文章,雖然可以在Android系統中通過非直接接觸的形式與支持NFC硬體的設備通信,但是也只能互動一些簡短的標簽內容,對大量的持續性資料,卻并不能很好的支持,因此針對這個弊端,可以考慮使用支持Bluetooth技術的硬體,
Android系統支持傳統的Bluetooth技術,其實作功能不僅可以傳輸資料,還可以傳輸并執行遠程控制指令,在Android4.3 即API 18 及以后的版本中,低功耗的Bluetooth技術(簡稱為BLE)取自傳統Bluetooth的核心功能,可以更省功耗并支持資料傳輸功能,在傳統藍牙技術中,應用程式所持有的藍牙設備可以作為藍牙服務端,開啟藍牙等待處理其他藍牙設備的接入請求;也可以作為藍牙客戶端,開啟藍牙查找附近的藍牙設備并請求接入,而在BLE技術中,應用程式所持有的藍牙設備只能作為GATT客戶端,連接其他類似藍牙耳機等BLE設備,下面應用程式將會以這三種身份分別說明,

權限宣告

使用Bluetooth技術,需要在清單檔案中宣告藍牙相關權限,申請權限使用<uses-permission />標簽,并設定其android:name屬性為對應的權限名,藍牙相關權限中主要有三種權限,申請后可分別對應執行不同功能,首先是可以執行藍牙通信的基礎權限,其值為Manifest.permission.BLUETOOTH="android.permission.BLUETOOTH";在需要通過藍牙獲取位置資訊的應用程式中,還需要獲取位置權限,其值為Manifest.permission.ACCESS_FINE_LOCATION="android.permission.ACCESS_FINE_LOCATION";另外如果需要使用藍牙的遠程控制功能,需要藍牙管理員權限,其值為Manifest.permission.BLUETOOTH_ADMIN="android.permission.BLUETOOTH_ADMIN"

使用流程

由于一個Android系統的設備上只能使用唯一的一個藍牙硬體,因此應用程式中可以通過android.bluetooth.BluetoothAdapter藍牙配接器操作底層的藍牙硬體,

設定藍牙

呼叫BluetoothAdapter中的靜態方法getDefaultAdapter()可以獲取到BluetoothAdapter藍牙配接器物件,但是,從Android 12即API 31開始就廢棄了上述方法,取而代之的是借助android.bluetooth.BluetoothManager藍牙管理類,在能獲取到Context背景關系環境類物件的位置,呼叫其getSystemService(String name)方法,傳入引數 name 值為Context.BLUETOOTH_SERVICE="bluetooth",可以獲取到BluetoothManager藍牙管理類的實體化物件,進而呼叫該物件的getAdapter()方法獲取已經實體化的BluetoothAdapter藍牙配接器物件,

對于不支持藍牙硬體的設備,得到的藍牙配接器物件為null,因此記得在應用程式中做非空判斷的相關操作!

在支持藍牙的設備上得到BluetoothAdapter物件后,還要確保設備已經開啟了藍牙功能,呼叫該物件的isEnabled()方法,根據回傳的boolean型別結果,判斷該設備是否已經正常開啟了藍牙功能;如果藍牙處于未啟用狀態,還要通過呼叫Context背景關系環境物件的startActivityForResult(Intent intent, int requestCode)方法跳轉到藍牙功能開啟界面,而這里傳入的引數 intent 則是標記為藍牙界面的Intent意圖物件,在該物件中設定其 action 值為BluetoothAdapter.ACTION_REQUEST_ENABLE ="android.bluetooth.adapter.action.REQUEST_ENABLE",在跳轉到藍牙功能界面后,需要由用戶手動選擇開啟藍牙,并回傳當前界面后,才能繼續執行后續操作,

藍牙客戶端查找其他藍牙設備

在設定藍牙等操作之后,就是查找該設備附近范圍內其他開啟藍牙功能的設備了,可以直接呼叫BluetoothAdapter物件的startDiscovery()方法來開啟查找附近設備的功能,但是在發現設備后,系統會通過廣播的形式發送已發現的設備資訊給應用程式,所以還需要在某個自定義界面Activity或者服務Service中,注冊BroadcastReceiver以接收該廣播,

注冊廣播的方式可以回顧BroadcastReceiver動態注冊部分內容,這里只是需要創建的IntentFilter意圖過濾物件中的引數 action 值為BluetoothDevice.ACTION_FOUND="android.bluetooth.device.action.FOUND",同時在自定義的BroadcastReceiver中處理收到的onReceive(Context context, Intent intent)方法中,對引數 intentgetParcelableExtra(String name)方法,并設定 name 值為BluetoothDevice.EXTRA_DEVICE="android.bluetooth.device.extra.DEVICE",可以獲得android.bluetooth.BluetoothDevice藍牙硬體設備類物件,在該物件中可以獲取查找到的藍牙硬體相關資訊,

在查找到設備后,要及時呼叫BluetoothAdapter物件的cancelDiscovery()方法關閉查找功能,否則設備的藍牙硬體會一直占用cpu資源并消耗電量,而且在后續的建立連接及資料傳輸時,也會由于藍牙發現功能的開啟占用大量帶寬而影響后續操作效率,

對于之前已經連接配對過的設備,就不需要通過上述查找藍牙的方式發現設備了,可以通過呼叫BluetoothAdapter物件的getBondedDevices()方法,直接獲取已配對過的藍牙設備,回傳BluetoothDevice物件組成的Set集合,

藍牙服務端等待其他設備連接請求

在設定藍牙操作后,如果想將該設備作為被發現的設備等待連接,需要啟動藍牙的可檢測功能,與開啟藍牙功能界面的方法類似,呼叫Context背景關系環境物件的startActivityForResult(Intent intent, int requestCode)方法跳轉到啟動藍牙可檢測性功能界面,傳入的引數 intent 意圖物件中,設定的 action 值為BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE="android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";另外可以通過putExtra(String name, int value)設定可檢測時間,其引數 name 值為BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION="android.bluetooth.adapter.extra.DISCOVERABLE_DURATION",而引數 value 值為int型別的數值,單位為秒,

同樣在跳轉到藍牙可檢測性功能界面后,需要由用戶手動確認開啟,才能等待被其他藍牙設備查找發現,同時不管用戶確認開啟或取消開啟功能,都會將結果回呼到Context背景關系環境所代表的原啟動界面Activity中的onActivityResuslt(int requestCode, int resultCode, Intent data)方法中,

藍牙Gatt客戶端查找其他BLE設備

在設定藍牙操作后,如果只是想查找附近的BLE設備并建立連接,則需要先拿到android.bluetooth.le.BluetoothLeScannerBLE掃描類物件,通過BluetoothAdapter物件的getBluetoothLeScanner()方法,可以得到BluetoothLeScannerBLE掃描類物件,之后借助該物件的startScan(ScanCallback callback)等系列方法,開始掃描查找附近的BLE設備,在查找到符合條件的設備后,會回呼android.bluetooth.le.ScanCallback型別的引數 callback 物件中的onScanResult(int callbackType, ScanResult result)方法,并將結果保存在android.bluetooth.le.ScanResult掃描結果型別的引數 result 物件中,在ScanResult物件中,可以獲得連接的BLE設備BlutoothDevice物件及連接所使用的協議功能等資訊,

掃描查找到BLE設備后,及時呼叫BluetoothLeScanner物件的stopScan(ScanCallback callback)方法,引數 callback 與上文開始查找附近BLE設備方法中的引數相同,以停止當前藍牙掃描查找功能,

連接藍牙

在上述查找藍牙或藍牙可檢測功能開啟后被其他設備連接后,都會得到對方的BlutetoothDevice藍牙設備類物件,通常,應用程式所在設備查找到其他藍牙設備后,可以主動向設備建立連接請求;而當應用程式所在設備開啟藍牙可檢測功能等待其他設備查找到時,只能被動的開啟連接服務,等待處理其他設備的連接請求,

藍牙客戶端發起連接請求

對于主動發起藍牙連接請求的方式,由得到的BluetoothDevice物件呼叫createRfcommSocketToServiceRecord(UUID uuid)方法,可以創建遠程socket連接,引數 uuid 是自定義的java.util.UUID唯一索引類物件,該值必須與后文提到的被動等待連接的藍牙設備中的監聽服務中的唯一索引值一致,該方法會回傳android.bluetooth.BluetoothSocket類用以保存創建的遠程藍牙socket連接,

在得到BluetoothSocket物件后,直接呼叫該物件的connect()方法發起連接請求,該方法呼叫后會一直等待連接的建立,只有建立連接后才會正常回傳并執行后續操作,否則,如果請求超時或連接失敗,該方法會拋出java.io.IOException例外,

藍牙服務端等待處理連接

對于被動等待建立連接的方式,由得到的BluetoothDevice物件呼叫listenUsingRfcommWithServiceRecord(String name, UUID uuid)方法,建立持續監聽服務,引數 name 是為該服務定義的名字;引數 uuid 是監聽的唯一索引值,其值與上文中主動發起藍牙連接請求是創建遠程socket連接所傳入的引數一致,該方法回傳android.bluetooth.BluetoothServerSocket藍牙連接的服務端socket類,用以保存在等待建立連接時的socket物件,

在得到BluetoothServerSocket物件后,直接呼叫該物件的accept()方法監聽連接請求,該方法呼叫后也會一致等待監聽狀態,只有監聽到匹配的連接請求后,才會回傳BluetoothSocket物件,否則,如果連接失敗,該方法同樣會拋出java.io.IOException例外,

對于上述兩種建立連接方式執行之后,便可以通過BluetoothSocket物件在藍牙客戶端和服務端之間傳輸資料,該物件的getInputStream()getOutputStream()方法可以分別獲取socket連接的InputStream資料輸入流物件和OutputStream資料輸出流物件,可以借助InputStream資料輸入流的read()系列方法,從socket連接中讀取資料到應用程式中,反之借助OutputStream資料輸出流的write()系列方法,將應用程式中的資料寫入到socket連接中,同樣地,這里的資料輸入流的讀取系列方法會一直處于等待讀取狀態,直到讀到指定長度資料后才會回傳結果,而資料輸出流的寫入系列方法,會在對方資料輸入流讀取慢導致寫入快取滿時處于一直等待寫入狀態,直到指定資料完全寫入才會回傳結果,

BluetoothServerSocketBluetoothSocket物件傳輸資料結束后,需要分別呼叫他們的close()方法關閉連接,防止遠程socket連接一直處于占用資源狀態,

Gatt客戶端連接BLE設備

對于Gatt客戶端連接方式,由得到的BluetoothDevice物件呼叫connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)系列方法連接BLE設備的Gatt服務端,引數 context 是當前應用程式所在的背景關系環境物件,引數 autoConnect 標識是否在連接該設備后自動建立Gatt服務連接,引數 callback 是建立Gatt服務連接后的回呼android.bluetooth.BluetoothGattCallback抽象類,

在初次連接其他BLE設備的Gatt服務端時,會回呼引數 callback 中的onServicesDiscovered(BluetoothGatt gatt, int status) 方法,而當已建立的Gatt連接狀態發生改變時,會回呼引數 callback 中的onConnectionStateChange(BluetoothGatt gatt, int status, int newState)方法,其他連接狀態也會對應BluetoothGattCallback類中的相關方法,

BluetoothGattCallback抽象類的回呼方法中,Gatt服務連接資訊是通過android.bluetooth.BluetoothGatt類的引數 gatt 來傳遞的,通過BluetoothGatt物件的相關方法,可以執行Gatt客戶端的連接及協議控制等操作,具體可需根據應用程式需求實作,只是記得在執行完相關操作后,呼叫引數 gattclose()方法關閉連接,

————————————————————————————————————————————————————————

———————————————————————————————轉載請注明出處:白少木丿—————————————————

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/423193.html

標籤:其他

上一篇:來自開發者的點贊!HMS Core榮獲多個行業獎項

下一篇:如果我沒有獲得www域的SSL密鑰,我是否面臨在nginx中將www重定向到非www的風險?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more