① android-Ble藍牙開發Demo示例–掃描,連接,發送和接收數據,分包解包(附源碼)
萬物互聯的物聯網時代的已經來臨,ble藍牙開發在其中扮演著舉重若輕的角色。最近剛好閑一點,抽時間梳理下這塊的知識點。
涉及ble藍牙通訊的客戶端(開啟、掃描、連接、發送和接收數據、分包解包)和服務端(初始化廣播數據、開始廣播、配置Services、Server回調操作)整個環節以及一些常見的問題即踩過的一些坑。
比如
1、在Android不同版本或不同手機的適配問題,掃描不到藍牙設備
2、如何避免ble藍牙連接出現133錯誤?
3、單次寫的數據大小有20位元組限制,如何發送長數據
藍牙有傳統(經典)藍牙和低功耗藍牙BLE(Bluetooth Low Energy)之分,兩者的開發的API不一樣,本文主講Ble藍牙開發,傳統藍牙不展開,有需要的可以自行了解。
相對傳統藍牙,BLE低功耗藍牙,主要特點是快速搜索,快速連接,超低功耗保持連接和數據傳輸。
客戶端
服務端
Android4.3(API Level 18)開始引入BLE的核心功能並提供了相應的 API。應用程序通過這些 API 掃描藍牙設備、查詢 services、讀寫設備的 characteristics(屬性特徵)等操作。
BLE藍牙協議是GATT協議, BLE相關類不多, 全都位於android.bluetooth包和android.bluetooth.le包的幾個類:
android.bluetooth.
.BluetoothGattService 包含多個Characteristic(屬性特徵值), 含有唯一的UUID作為標識
.BluetoothGattCharacteristic 包含單個值和多個Descriptor, 含有唯一的UUID作為標識
.BluetoothGattDescriptor 對Characteristic進行描述, 含有唯一的UUID作為標識
.BluetoothGatt 客戶端相關
.BluetoothGattCallback 客戶端連接回調
.BluetoothGattServer 服務端相關
.BluetoothGattServerCallback 服務端連接回調
android.bluetooth.le.
.AdvertiseCallback 服務端的廣播回調
.AdvertiseData 服務端的廣播數據
.AdvertiseSettings 服務端的廣播設置
.BluetoothLeAdvertiser 服務端的廣播
.BluetoothLeScanner 客戶端掃描相關(Android5.0新增)
.ScanCallback 客戶端掃描回調
.ScanFilter 客戶端掃描過濾
.ScanRecord 客戶端掃描結果的廣播數據
.ScanResult 客戶端掃描結果
.ScanSettings 客戶端掃描設置
BLE設備分為兩種設備: 客戶端(也叫主機/中心設備/Central), 服務端(也叫從機/外圍設備/peripheral)
客戶端的核心類是 BluetoothGatt
服務端的核心類是 BluetoothGattServer 和 BluetoothLeAdvertiser
BLE數據的核心類是 BluetoothGattCharacteristic 和 BluetoothGattDescriptor
下面詳細講解下客戶端和服務端的開發步驟流程
安卓手機涉及藍牙許可權問題,藍牙開發需要在AndroidManifest.xml文件中添加許可權聲明:
在搜索設備之前需要詢問打開手機藍牙:
注意: BLE設備地址是動態變化(每隔一段時間都會變化),而經典藍牙設備是出廠就固定不變了!
通過掃描BLE設備,根據設備名稱區分出目標設備targetDevice,下一步實現與目標設備的連接,在連接設備之前要停止搜索藍牙;停止搜索一般需要一定的時間來完成,最好調用停止搜索函數之後加以100ms的延時,保證系統能夠完全停止搜索藍牙設備。停止搜索之後啟動連接過程;
BLE藍牙的連接方法相對簡單只需調用connectGatt方法;
參數說明
與設備建立連接之後與設備通信,整個通信過程都是在BluetoothGattCallback的非同步回調函數中完成;
BluetoothGattCallback中主要回調函數如下:
上述幾個回調函數是BLE開發中不可缺少的;
當調用targetdDevice.connectGatt(context, false, gattCallback)後系統會主動發起與BLE藍牙設備的連接,若成功連接到設備將回調onConnectionStateChange方法,其處理過程如下:
判斷newState == BluetoothGatt.STATE_CONNECTED表明此時已經成功連接到設備;
mBluetoothGatt.discoverServices();
掃描BLE設備服務是安卓系統中關於BLE藍牙開發的重要一步,一般在設備連接成功後調用,掃描到設備服務後回調onServicesDiscovered()函數,函數原型如下:
BLE藍牙開發主要有負責通信的BluetoothGattService完成的。當且稱為通信服務。通信服務通過硬體工程師提供的UUID獲取。獲取方式如下:
具體操作方式如下:
開啟監聽,即建立與設備的通信的首發數據通道,BLE開發中只有當客戶端成功開啟監聽後才能與服務端收發數據。開啟監聽的方式如下:
BLE單次寫的數據量大小是有限制的, 通常是20位元組 ,可以嘗試通過requestMTU增大,但不保證能成功。分包寫是一種解決方案,需要定義分包協議,假設每個包大小20位元組,分兩種包,數據包和非數據包。對於數據包,頭兩個位元組表示包的序號,剩下的都填充數據。對於非數據包,主要是發送一些控制信息。
監聽成功後通過向 writeCharacteristic寫入數據實現與服務端的通信。寫入方式如下:
其中:value一般為Hex格式指令,其內容由設備通信的藍牙通信協議規定;
若寫入指令成功則回調BluetoothGattCallback中的onCharacteristicWrite()方法,說明將數據已經發送給下位機;
若發送的數據符合通信協議,則服務端會向客戶端回復相應的數據。發送的數據通過回調onCharacteristicChanged()方法獲取,其處理方式如下:
通過向服務端發送指令獲取服務端的回復數據,即可完成與設備的通信過程;
當與設備完成通信之後之後一定要斷開與設備的連接。調用以下方法斷開與設備的連接:
源碼上傳在CSDN上了,有需要的可以借鑒。
=====> Android藍牙Ble通訊Demo示例源碼–掃描,連接,發送和接收數據,分包解包
BLE單次寫的數據量大小是有限制的,通常是20位元組,可以嘗試通過requestMTU增大,但不保證能成功。分包寫是一種解決方案,需要定義分包協議,假設每個包大小20位元組,分兩種包,數據包和非數據包。對於數據包,頭兩個位元組表示包的序號,剩下的都填充數據。對於非數據包,主要是發送一些控制信息。
總體流程如下:
1、定義通訊協議,如下(這里只是個舉例,可以根據項目需求擴展)
2、封裝通用發送數據介面(拆包)
該介面根據會發送數據內容按最大位元組數拆分(一般20位元組)放入隊列,拆分完後,依次從隊列里取出發送
3、封裝通用接收數據介面(組包)
該介面根據從接收的數據按協議里的定義解析數據長度判讀是否完整包,不是的話把每條消息累加起來
4、解析完整的數據包,進行業務邏輯處理
5、協議還可以引入加密解密,需要注意的選演算法參數的時候,加密後的長度最好跟原數據長度一致,這樣不會影響拆包組包
一般都是Android版本適配以及不同ROM機型(小米/紅米、華為/榮耀等)(EMUI、MIUI、ColorOS等)的許可權問題
藍牙開發中有很多問題,要靜下心分析問題,肯定可以解決的,一起加油;
② Android藍牙協議-藍牙配對與連接
藍牙設備在連接前,會先檢查設備是否已經配對過,如果沒有則先配對,配對完成後,再開始連接。
藍牙連接開始於設備列表 DeviceListPreferenceFragment的onPreferenceTreeClick方法。
DeviceListPreferenceFragment是藍牙設備列表,點擊其中一個藍牙設備,開始藍牙的連接過程。
調用onDevicePreferenceClick方法,接著調用BluetoothDevicePreference的onClicked方法,開始連接,以及連接前的狀態檢測。
獲取mCachedDevice的綁定狀態,
pair方法會調用CachedBluetoothDevice.startPairing,啟動配對
createBond調用BluetoothDevice.createBond方法,BluetoothDevice.createBond接著調用IBluetooth.createBond方法,下面會調用藍牙遠程服務。
和藍牙掃描一樣,實現IBluetooth介面的類是AdapterServiceBinder,
AdapterServiceBinder實現IBluetooth.Stub介面,並且是AdapterService的私有內部類, AdapterServiceBinder接受事件,都會轉交AdapterService處理 ,所以IBluetooth.createBond方法會調用AdapterService.createBond方法。
createBond方法會檢查一下遠程設備屬性信息,再次取消藍牙掃描任務,將配對任務轉交mBondStateMachine,由狀態機處理該信息。
BondStateMachine狀態機的初始狀態是StableState,所以BondStateMachine.CREATE_BOND由StableState處理,StableState在processMessage中調用BondStateMachine.createBond方法
createBondNative方法實現com_android_bluetooth_btservice_AdapterService.cpp中
③ 安卓手機怎麼連藍牙
連接藍牙耳機的方法是:
1、打開藍牙耳機開關鍵,長按開關鍵,直到指示燈出現紅藍燈交替閃爍,進入配對狀態;
2、開啟手機藍牙功能,將手機藍牙設置為「所有人可見」 或可被搜索或開放檢測,搜索藍牙設備;
3、查找到之後選中進行配對連接,(如有的需輸入密碼的,則在手機輸入配對密碼:0000有的配對密碼是:1234),連接成功則完成配對;
4、在手機撥打電話,可用藍牙耳機接聽;在手機上播放音樂,可在藍牙耳機上欣賞音樂。
④ Android開發之藍牙(Bluetooth)
在上一篇中有介紹了Wifi與網路連接處理
Android開發之WiFi與網路連接處理
下面,來繼續說說Android中藍牙的基本使用。
Bluetooth是目前使用的最廣泛的無線通訊協議之一,主要針對短距離設備通訊(10米),常用於連接耳機、滑鼠和移動通訊設備等。
值得一提的是:
android4.2新增了部分新功能,但是對於Bluetooth熟悉的人或許開始頭疼了,那就是Android4.2引入了一個新的藍牙協議棧針BLE。谷歌和Broadcom之間的合作,開發新的藍牙協議棧,取代了基於堆棧的Bluez。因此市場上出現了老設備的兼容問題,很多藍牙設備在android4.2手機上不能正常使用。
BluetoothAdapter簡單點來說就是代表了本設備(手機、電腦等)的藍牙適配器對象。
first:we need permission
要操作藍牙,先要在AndroidManifest.xml里加入許可權
**下面來看看如何使用藍牙。 **↓↓↓****
Demo已就緒:
返回值:如果設備具備藍牙功能,返回BluetoothAdapter 實例;否則,返回null對象。
打開藍牙設備的方式:
1.直接調用函數enable()去打開藍牙設備 ;
2.系統API去打開藍牙設備,該方式會彈出一個對話框樣式的Activity供用戶選擇是否打開藍牙設備。
注意: 1.如果藍牙已經開啟,不會彈出該Activity界面。2.在目前大多數Android手機中,是不支持在飛行模式下開啟藍牙的。如果藍牙已經開啟,那麼藍牙的開關 ,狀態會隨著飛行模式的狀態而發生改變。
1. 搜索藍牙設備
使用BluetoothAdapter的startDiscovery()方法來搜索藍牙設備
startDiscovery()方法是一個非同步方法,調用後會立即返回。該方法會進行對其他藍牙設備的搜索,該過程會持續12秒。該方法調用後,搜索過程實際上是在一個System Service中進行的,所以可以調用cancelDiscovery()方法來停止搜索(該方法可以在未執行discovery請求時調用)。
系統開始搜索藍牙設備
^( *  ̄(oo) ̄ ) ^ 系統會發送以下三個廣播:
2.掃描設備
3.定義廣播接收器接收搜索結果
4.注冊廣播
獲取附近的藍牙設備
第一步建立連接:首先Android sdk(2.0以上版本)支持的藍牙連接是通過BluetoothSocket建立連接,服務端BluetoothServerSocket和客戶端(BluetoothSocket)需指定同樣的UUID,才能建立連接,因為建立連接的方法會阻塞線程,所以伺服器端和客戶端都應啟動新線程連接。
(這里的服務端和客戶端是相對來說的)
兩個藍牙設備之間的連接,則必須實現服務端與客戶端的機制。
當兩個設備在同一個RFCOMM channel下分別擁有一個連接的BluetoothSocket,這兩個設備才可以說是建立了連接。
服務端設備與客戶端設備獲取BluetoothSocket的途徑是不同的。
1,服務端設備是通過accepted一個incoming connection來獲取的,
2,客戶端設備則是通過打開一個到服務端的RFCOMM channel來獲取的。
服務端
通過調用BluetoothAdapter的(String, UUID)方法來獲取BluetoothServerSocket(UUID用於客戶端與服務端之間的配對)
客戶端
調用BluetoothService的(UUID)方法獲取BluetoothSocket(該UUID應該同於服務端的UUID)。
調用BluetoothSocket的connect()方法(該方法為block方法),如果UUID同服務端的UUID匹配,並且連接被服務端accept,則connect()方法返回。
數據傳遞,通過以上操作,就已經建立的BluetoothSocket連接了,數據傳遞無非是通過流的形式
獲取流
該類就是關於遠程藍牙設備的一個描述。通過它可以和本地藍牙設備---BluetoothAdapter連接通信。
好多東西我也不知道怎麼描述,下面給出Demo:
剛好有剛學習的小夥伴問我ListView怎麼用,那我就用ListView。
源碼:
RairDemo
GitHub: https://github.com/Rairmmd/android-demo
Coding: https://coding.net/u/Rair/p/RairDemo/git
⑤ Android 藍牙開發(一)
普通藍牙設備官方文檔
Android 平台包含藍牙網路堆棧支持 ,憑藉此支持,設備能以無線方式與其他藍牙設備交換數據。應用框架提供了通過 Android Bluetooth API 訪問藍牙功能的途徑。使用 Bluetooth API Android 應用可以執行下面的操作:
傳統藍牙適用於電池使用強度較大的操作,例如 Android 設備之間的流傳輸和通信等。針對具有低功耗要求的藍牙設備,Android 4.3(API 18)中引入了面向低功耗藍牙的 API 支持。
使用 Android Bluetooth API 來完成使用藍牙進行通信的四項主要任務: 設置藍牙 、 查找局部區域內的配對設備或可用設備 、 連接設備 ,以及在 設備之間傳輸數據 。
關於藍牙的 API 在 android.bluetooth 包中,下面介紹一下和藍牙相關的主要類:
在 BluetoothProfile IPC 客戶端連接到服務(即,運行特定配置文件的內部服務)或斷開服務連接時向其發送通知的介面。
使用藍牙必須聲明許可權 BLUETOOTH 才可以執行藍牙通信。
1、獲取藍牙適配器
例如:我們可以查詢所有已配對的設備,然後使用 ArrayAdapter 向用戶顯示每台設備的名稱:
要發起連接僅需要知道目標藍牙設備的 Mac 地址就可以了。
注意 執行 discovery 對於藍牙適配器來說是一個非常繁重的過程,並且會消耗大量資源。在找到要連接的設備後, 要確保使用 cancelDiscovery() 來停止發現,然後嘗試連接 。如果您已經和某台設備進行連接,那麼這個時候執行發現操作會大幅度的減少此連接可用的帶寬!因此不應該在處於連接狀態的時候執行發現操作!
例如:
在連接之前如果兩個設備沒有配對,則系統會自動發出配對請求。
伺服器套接字接受連接的基本過程
放在子線程中去執行。
例子:
客戶端連接的基本過程
調用 connect() 的時候要確保客戶端沒有執行發現操作。如果執行了會大幅度降低連接的速度,增加失敗的可能。
例子
在連接之前調用 cancleDiscovery() 在進行連接之前應該始終調用這個方法,而且調用的時候無需檢測是否正在掃描。
過程:
從 Android 3.0 開始, Bluetooth API 便支持使用藍牙配置文件。藍牙配置文件是適用於設備間藍牙通信的無線介面規范。
1、藍牙配置文件就是設備間通信(藍牙設備)的一種規范
免提配置文件便是一個示例,對於連接到無線耳機的手機,兩台設備都必須支持免提配置文件。我們也可以通過實現介面 BluetoothProfile 來寫入自己的類來支持特定的藍牙配置文件。Android API 提供了以下的幾種藍牙配置文件的實現:
2、使用配置文件的基本步驟
創建 HDP 應用:
關於普通藍牙設備和普通藍牙設備之間的連接通信
關於藍牙設備和藍牙儀器(藍牙耳機、電子秤等等類似產品)
這種之間的通信是通過配置文件代理來實現的。
都有一個對應的配置文件代理類。具體的操作是通過這個對象來完成。
參考: https://mp.weixin.qq.com/s?__biz=MzU5NzA2NjQzMg==&mid=2247484128&idx=1&sn=&scene=21#wechat_redirect
⑥ syu android藍牙連接方法
syu android藍牙連接方法:打開其他設備的藍牙,並使其對其他設備可見。打開下拉頂簾,點擊藍牙圖標使其變為綠色,跳出提示框,勾選對其他設備可見。
syu android判斷藍牙模塊是否開啟,blueadapter.isEnabled() true表示已經開啟,false表示藍牙並沒啟用。
syu android啟動配置藍牙可見模式,即進入可配對模式Intent in=newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE)。
藍牙連接技術優勢:
支持語音和數據傳輸;採用無線電技術,傳輸范圍大,可穿透不同物質以及在物質間擴散;採用跳頻展頻技術,抗干擾性強,不易竊聽;使用在各國都不受限制的頻譜,理論上說,不存在干擾問題;功耗低;成本低。藍牙的劣勢:傳輸速度慢。
藍牙的技術性能參數:有效傳輸距離為10cm~10m,增加發射功率可達到100米,甚至更遠。收發器工作頻率為2.45GHz ,覆蓋范圍是相隔1MHz的79個通道(從2.402GHz到2.480GHz )。