❶ android藍牙開發——實現藍牙聊天
與藍牙開發主要的相關類是以下四個
知道對應API後就可以進行對應的藍牙開發,這里以獲取藍牙設備為例子
}
搜索設備的回調則需要通過注冊廣播的形式來獲取
定義廣播
之後就可以進行個人的一些操作
要實現藍牙聊天則涉及到藍牙之間的傳輸通信,前面也說到了,這里肯定就是用到BluetoothServerSocket以及BluetoothSocket。
藍牙傳輸通信相當於伺服器端與客戶端之間的通信,只不過不同是這里每一個藍牙設備本身自己 既充當伺服器端也充當客戶端 ,大致的關系就是
注意,這些連接都是阻塞式的,都要放在線程里去執行。
可以看到,當BluetoothServerSocket監聽到有設備連接的時候,就會調用dataTransfer開啟一個數據傳輸。
需要一個ConnectThread來發起
之後建立連接之後就會調用dataTransfer來進行數據傳輸,同樣也需要一個線程來維護數據傳輸
藍牙聊天則是基於上面三個線程來進行實現,同樣,對於藍牙文件間的傳輸也是同個道理,通過輸入輸出流來進行處理。之後的操作就比較容易處理了
藍牙聊天
Android 藍牙開發基本流程
❷ 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 藍牙編程的基本步驟:
獲取藍牙適配器BluetoothAdapterblueadapter=BluetoothAdapter.getDefaultAdapter();
如果BluetoothAdapter 為null,說明android手機沒有藍牙模塊。
判斷藍牙模塊是否開啟,blueadapter.isEnabled() true表示已經開啟,false表示藍牙並沒啟用。
啟動配置藍牙可見模式,即進入可配對模式Intentin=newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
in.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,200);
startActivity(in); ,200就表示200秒。
獲取藍牙適配器中已經配對的設備Set<BluetoothDevice>device=blueadapter.getBondedDevices();
當然,還需要在androidManifest.xml中聲明藍牙的許可權
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
接下來就是根據自己的需求對BluetoothAdapter的操作了。
❹ android 藍牙 怎麼入門
入手一個新的模塊或應用,當然首先要知道它都有什麼了,與它相關的代碼在那裡,所以先一起看下藍牙代碼分布吧。
1. 代碼分布:
packages/apps/Bluetooth/
看這路徑肯定是藍牙應用方面的代碼了,主要是關於藍牙應用協議的表現代碼,包括opp、hfp、hdp、a2dp、pan等等,這些名詞後面再解釋。
frameworks/base/core/java/android/server/
4.2以後這個目錄雖然還有了,但裡面代碼已經轉移到應用層了,就是前面那個目錄,所以4.2.2上的藍牙這里可以忽略。
framework/base/core/java/android/bluetooth
這個目錄里的代碼更像一個橋梁,裡面有供java層使用一些類,也有對應的aidl文件聯系C、C++部分的代碼,還是挺重要的。
kerneldriversluetoothBluetooth
具體協議實現。包括hci,hid,rfcomm,sco,SDP等協議
kernel etluetooth Linux kernel
對各種介面的Bluetoothdevice的驅動。例如:USB介面,串口等,上面kernel這兩個目錄有可能看不到的,但一定會有的。
externalluetoothluedroid BlueZ (應用空間協議),官方藍牙協議棧。
systemluetoothBluetooth 適配層代碼,和framework那個作用類似,是串聯framework與blueZ的工具。
大致代碼分布就是這些,初步查看後讓我們再來看下藍牙的整體結構。
2.整體結構:
這部分直接上圖了,看著直觀些。圖中把JNI部分雖然在目前4.2的代碼中在packages層,這里還是畫在Framework層了,說明下希望
不要引起理解的誤會。從圖上可以感覺到整體流程和以前變化不大,所以流程方面的文章看4.1或更早的應該問題也不大。
PS:上圖關於藍牙協議棧的說明有誤,4.2里已經不再是bluez了,在些更正一下,當然協議棧這一部分還是要有的,新的協議棧看下面英文:
Android 4.2 introces a new Bluetooth stack optimized for use with Android devices. The new Bluetooth stack developed in
collaboration between Google and Broadcom replaces the stack based on BlueZ and provides improved compatibility and reliability.
google和broadcom合作開發了一個新藍牙協議棧,老版本的兼容性問題在所難免了。在此感謝網友andger032的提醒。
3.常用類和名詞解釋:
luetooth 目錄下
BluetoothEnabler.java 界面上藍牙開啟、關閉的開關就是它了,
BluetoothSettings.java 主界面,用於管理配對和連接設備
LocalBluetoothManager.java 提供了藍牙API上的簡單調用介面,這里只是開始。
CachedBluetoothDevice.java 描述藍牙設備的類,對BluetoothDevice的再封裝
BluetoothPairingDialog.java 那個配對提示的對話框
/packages/apps/Phone/src/com/android/phone/
BluetoothPhoneService.java 在phone的目錄肯定和電話相關了,藍牙接聽掛斷電話會用到這個
/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/
AdapterService.java 4.2後才有的代碼,藍牙打開、關閉、掃描、配對都會走到這里,其實更准確的說它替代了4.1之前的BluetoothService.java,原來的工作就由這個類來完成了。說到這里不能不說4.2藍牙的目錄變了,在4.1及以前的代碼中packages層的代碼只有opp協議相關應用的代碼,也就是文件傳輸那部分,而4.2的代碼應用層的代碼則豐富了許多,按具體的藍牙應用協議來區別,分為以下文件夾(這里一並對藍牙一些名詞作個簡單解釋):
a2dp 藍牙立體聲,和藍牙耳機聽歌有關那些,另還有個avrcp--音頻/視頻遠程式控制制配置文件,是用來聽歌時暫停,上下歌曲選擇的。
btservice 這個前面AdapterService.java的描述大家應該能猜到一些,關於藍牙基本操作的目錄,一切由此開始。
hdp 藍牙關於醫療方面的應用 Bluetooth Health Device Profile
hfp 和電話相關,藍牙接聽、掛斷電話 Hands-free Profile
hid 人機交互介面,藍牙滑鼠鍵盤什麼的就是這個了
opp 不多解釋,以前就有。
pan 描述了兩個或更多個 Bluetooth 設備如何構成一個即時網路,和網路有關的還有串列埠功能(SPP),撥號網路功能(DUN)
pbap 電話號碼簿訪問協議(Phonebook Access Profile)
android 4.2的藍牙應用層部分代碼更豐富了,雖然有些目錄還沒具體代碼,不過說不準哪個版本更新就有了,就像4.0添加了hdp醫療那部分一樣。
另外原本在framework的JNI代碼也被移到packages/apps/bluetooth當中。
/frameworks/base/core/java/android/bluetooth/目錄下
BluetoothA2dp.java A2DP的功能實現
BluetoothAdapter.java 藍牙action的定義,虛擬設備屬性以及操作方法
BluetoothAudioGateway.java 藍牙語音網關
BluetoothClass.java 藍牙設備類型的定義
BluetoothDevice.java 藍牙設備屬性
BluetoothDevicePicker.java 定義遠程藍牙設備的特性,比如需要認證,設備類型
BluetoothHeadset.java 定義藍牙headset功能的屬性以及介面
BluetoothInputStream.java 藍牙流介面的實現(輸入流)
BluetoothOutputStream.java 藍牙流介面的實現(輸出流)
BluetoothServerSocket.java 藍牙socket服務端具備的方法
BluetoothSocket.java 藍牙socket的封裝
BluetoothUuid.java 藍牙uuid的定義以及uuid的解析
以上java文件在使用具體功能會用到,現在只是簡單描述下,至於具體使用在後續文章用到時再給出。同時代碼說明部分也就寫這些了
對於C、C++部分的代碼一方面沒看那麼多,另一方面根據android JNI的命名習慣,大家找起來也很容易。
4.後續分析:
前面從整體上描述藍牙的基本知識,落實在具體的代碼分析上,我們按幾個主線功能來走,藍牙的開關、搜索配對、藍牙耳機與電話和文件傳輸,
這幾個也算是藍牙的常用必備功能了,所以在後續文章中將按著這個順序來跟一下它們代碼調用流程。希望可以讓你快速的了解藍牙,當然如果有失誤
轉載
❺ 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
❻ Android藍牙開發(二)經典藍牙消息傳輸實現
上篇文章中,我們主要介紹了藍牙模塊,傳統/經典藍牙模塊BT和低功耗藍牙BLE及其相關的API,不熟悉的可以查看 Android藍牙開發(一)藍牙模塊及核心API 進行了解。
本篇主要記錄用到的經典藍牙開發流程及連接通訊。
藍牙連接前,給與相關系統許可權:
安卓6.0以上系統要動態請求及獲取開啟GPS內容:
藍牙核心對象獲取,若獲取對象為null則說明設備不支持藍牙:
判斷藍牙是否開啟,沒有則開啟:
藍牙掃描:
取消掃描:
藍牙監聽廣播,監聽藍牙開關,發現設備,掃描結束等狀態,定義狀態回調介面,進行對應操作,例如:監聽到藍牙開啟後,進行設備掃描;發現設備後進行連接等。
客戶端,與服務端建立長連接,進行通訊:
服務端監聽客戶端發起的連接,進行接收及通訊:
客戶端連接及服務端監聽基類,用於客戶端和服務端之前Socket消息通訊,進行消息或文件的發送、接收,進行通訊關閉操作等:
我這里只是簡單記錄了項目中用到的藍牙通訊,兩個設備之間不通過配對進行連接、通訊。
相關詳細內容及使用請查看Github項目: https://github.com/MickJson/BluetoothCS
藍牙配對操作及其它內容,可以詳細查看我下面的參考資料,寫的十分詳細,比如設備通過MAC地址,可以通過BluetoothAdapter獲取設備,再通過客戶端connect方法去進行連接等。
連接中遇到問題:read failed, socket might closed or timeout, read ret: -1。
通過改UUID,反射等方法都還是會出現錯誤。連接時,要確保服務端及客戶端都處於完全斷開狀態,否則連接就會出現以上問題,但偶爾還是會有問題,期待有什麼好的方法可留言告訴我。
參考資料:
Android-經典藍牙(BT)-建立長連接傳輸短消息和文件
Android藍牙開發—經典藍牙詳細開發流程
歡迎點贊/評論,你們的贊同和鼓勵是我寫作的最大動力!
❼ Android 藍牙開發(三)-藍牙的詳細介紹
前面的兩篇文章,主要是在 Android 官網關於藍牙介紹的基礎上加上自己的理解完成的。主要針對的是 Android 開發中的一些 API 的使用。
第一篇文章 Android 藍牙開發(一) 主要是介紹了普通的藍牙在 Android 開發中的運用。
第二篇文章 Android 藍牙開發(二) 主要是介紹了低功耗藍牙的開發。
這篇文章主要介紹的是藍牙的歷史和一些關於藍牙的通用知識,還有廣播包的知識。要想徹底了解藍牙開發,這些基礎的知識也是需要的,就像網路協議一樣,這些都是基礎的內容。我們的 API 的調用都是以這個為基礎的,了解這些,開發過程中遇到問題,才可以知道什麼怎麼一回事。
下篇文章主要講的就是實際開發中的一些坑。
藍牙其實就是一種近距離無線通信技術。
從下到上分別為:控制器(Controller)-->主機(host)-->應用(Application)
詳細介紹各個層的含義:
BLE 應用可以分為兩大類:基於非連接的和基於連接的
意思就是外設和周邊設備不發生連接,主要靠掃描到的廣播來獲取信息。發送廣播的一方叫做 broadcaster 監聽廣播的一方叫做 oberver 在 GAP 層有對應的角色定義。
網路拓撲圖:
這種方式就是廣播設備不斷的向外發送廣播(含有特定的信息),然後觀察者接受到廣播按照兩者之間約定好的協議進行解析拿到有用的信息。例如:iBeacon,通過這種設備我們可以實現室內定位。
其實這些設備的角色可以即使廣播者又是觀察者。接收到廣播後作出了處理,然後又發送廣播。這樣就形成了雙向的網路,類似於網際網路,這就是藍牙 Mesh 組網。
廣播數據包格式:
每個廣播數據包由 31 byte 組成。分為有效數據和無效數據兩部分。
例子:
這里是掃描的數據包(轉換成了 16 進制,兩個代表一個位元組),第一個位元組是 02 表示後面的兩個位元組是數據部分,然後第二個位元組是 01 表示了數據的類型。後面一個位元組就是真正的數據了。這個廣播數據單元就分析完了。下面就是另一個數據單元了。依次類推,關於數據類型的解釋,官網有。
這是數據類型對應的含義表。
網路拓撲圖:
一個中心設備可連接多個外設,但是一個外設只能連接一個中心(外設連接成功後就會停止對外廣播,別人就發現不了它了)。其中一個中心設備的連接外設的數量也是有限的。
鏈接: https://mp.weixin.qq.com/s?__biz=MzU5NzA2NjQzMg==&mid=2247484141&idx=1&sn=&scene=21#wechat_redirect
❽ Android中如何實現藍牙的配對與連接
藍牙功能可以參考下面的操作打開使用:
1.打開其他設備的藍牙,並使其對其他設備可見。
2.打開下拉頂簾,點擊藍牙圖標使其變為綠色,跳出提示框,勾選對其他設備可見。
3.點擊掃描,搜索到其他設備後,點擊該設備名稱,雙方點確定後配對成功。
4.選擇要傳輸的文件,共享通過藍牙即可傳輸文件。