❶ android-藍牙傳輸
通過藍牙傳輸數據與Socket類似。在網路中使用Socket和ServerSocket控制客戶端和服務端的數據讀寫。而藍牙通訊也由客戶端和服務端Socket來完成。藍牙客戶端Socket是BluetoothSocket,藍牙服務端Socket是BluetoothServerSocket。這兩個類都在android.bluetooth包中。
如果打算建議兩個藍牙設備之間的連接,則必須實現伺服器端與客戶端的機制。當兩個設備在同一個RFCOMM channel下分別擁有一個連接的BluetoothSocket,這兩個設備才可以說是建立了連接。
伺服器設備與客戶端設備獲取BluetoothSocket的途徑是不同的。伺服器設備是通過accepted一個incoming connection來獲取的,而客戶端設備則是通過打開一個到伺服器的RFCOMMchannel來獲取的。
通過調用BluetoothAdapter的(String, UUID) 方法來獲取
BluetoothServerSocket(UUID用於客戶端與伺服器端之間的配對)調用BluetoothServerSocket的 accept() 方法監聽連接請求,如果收到請求,則返回一個BluetoothSocket實例。
如果不想在accept其他的連接,則調用BluetoothServerSocket的 close() 方法釋放資源(調用該方法後,之前獲得的BluetoothSocket實例並沒有close。但由於RFCOMM一個時刻只允許在一條channel中有一個連接,則一般在accept一個連接後,便close掉BluetoothServerSocket)
通過搜索得到伺服器端的BluetoothService,調用BluetoothService的(String, UUID)方法獲取BluetoothSocket(該UUID應該同於伺服器端的UUID)。
調用BluetoothSocket的 connect() 方法(該方法為block方法),如果UUID同伺服器端的UUID匹配,並且連接被伺服器端accept,則 connect() 方法返回。
❷ 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中
❸ 如何使用android原生BLE藍牙進行操作
之前的涉及的物聯網項目中使用的: BLE 低功耗藍牙(藍牙4.0), 支持android 4.3以上的手機
主從關系: BLE低功耗藍牙只能做從端設備 ,一個藍牙主端設備,可同時與7個藍牙從端設備進行通訊
1)低功耗
低功耗的原理:
1低功耗藍牙僅使用了3個廣播通道,傳統藍牙技術採用 16~32 個頻道
2每次廣播開啟時間也由傳統的 22.5ms 減少到 0.6~1.2ms(毫秒)
2)傳輸距離極大提高
傳統藍牙傳輸距離為 2~10m,而藍牙4.0的有效傳輸距離可達到 60~100m
3)安全性
使用AES-128 CCM加密演算法進行數據包加密和認證。
更多BLE藍牙的解析參考博客 : BLE4.0教程一 藍牙協議連接過程與廣播分析
添加許可權
打開藍牙
1.先拿到BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
2.再拿到BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
判斷是否打開藍牙
未打開彈出 系統彈框 ,除了 魅族手機 是打開系統設置
設備/手機都是藍牙信號
在回調方法中:
一般在掃描的過程中,我們還會設置 設備過濾原則 (因為我只想要搜索到我們想要的設備,忽略無關設備)
如:從 scanRecord -- beacon -- beacon.type == 0xFF代表Manufacture,通過與嵌入式軟體定義 自己的 Manufacture值即可
用BluetoothDevice得到BluetoothGatt:
斷連:
關鍵問題:連接後一般要做什麼事?
( 必須在剛連接成功後2秒內app寫一個值給設備,否則會被設備斷開連接)
主要是讀寫 characteristic
gatt.wirteCharacteristic(mCurrentcharacteristic);
gatt.readCharacteristic(characteristic);
bluetoothGatt.setCharacteristicNotification(data, true);
真實工作中使用的藍牙庫BlueToothKit請參考我的另一篇博客:
android藍牙入門知識和優秀藍牙第三方庫BluetoothKit的使用
❹ 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 ble為什麼要用service
BLE分為三部分Service、Characteristic、Descriptor,這三部分都由UUID作為唯一標示符。一個藍牙4.0的終端可以包含多個Service,一個Service可以包含多個Characteristic,一個Characteristic包含一個Value和多個Descriptor,一個Descriptor包含一個Value。一般來說,Characteristic是手機與BLE終端交換數據的關鍵,Characteristic有較多的跟許可權相關的欄位,例如PERMISSION和PROPERTY,而其中最常用的是PROPERTY,本文所用的BLE藍牙模塊竟然沒有標準的Characteristic的PERMISSION。Characteristic的PROPERTY可以通過位運算符組合來設置讀寫屬性,例如READ|WRITE、READ|WRITE_NO_RESPONSE|NOTIFY,因此讀取PROPERTY後要分解成所用的組合(本文代碼已含此分解方法)。
❻ Android保活——藍牙喚醒(主動kill掉也可喚醒)
項目需要後台保活,但無論怎麼保活,只要用戶主動kill掉,app依然是活不了。
發現了藍牙喚醒這個方式,用戶主動kill掉也可行。
Android 8.0開始提供猜差了 startscan的方法,
public void startScan(ScanCallback callback)
public void startScan(List<ScanFilter> filters,ScanSettings settings,ScanCallback callback)
public int startScan(List<ScanFilter> filters,ScanSettings settings,PendingIntent callbackIntent)
第一個沒有過濾條件,鎖屏就停止掃描
第二個可以加過濾條件,鎖屏不影響掃描
第三個的掃描結果由PendingIntent發送,即使app沒有在運行,系統也可以掃描後喚醒app,這就是我們要的方法了。
PendingIntent是對Intent的封裝,是滿足某些條件或觸發某些事件後才執行指定的行為,主要用於鬧鍾、通知、桌面部件。Android的四大組件之間通信用Intent,跨進程通信用PendingIntent。
Android 8.0 引進了Context.startForegroundService(),在系統創建服務後,應纖神用需要在ANR發生前調用startForeground(int ,android.app.Notification),如果未及時調用該方法,系統將報ANR錯誤 。系統給前台服務的ANR時間是20秒。
用startScan藍牙喚醒的原理是:app向系統訂閱了掃描結果(預先加了過濾條件),當藍牙連接斷開的時候,設備就會發廣播,這時系統就可以掃描到對應的廣播,喚醒對應的service,這時想做什麼操作就根據你的項目需要了。至於系統會為你掃描多久,這個還沒測試。
(1)setScanMode有四個參數可以選 :
SCAN_MODE_BALANCED:在平衡電源模式下執行藍牙LE掃描。返回掃描結果的速度能夠很好地權衡掃描頻率和功耗。
SCAN_MODE_LOW_LATENCY:掃描使用最高占空比。建議只在應用程序在前台運行時使用此模式。
SCAN_MODE_LOW_POWER:在低功耗模式下執行藍牙LE掃描。這是默認的掃描模式,因為它消耗的能量最少。如果掃描應用程序不在前台,則強制執行此模式。
SCAN_MODE_OPPORTUNISTIC:一種特殊的藍牙LE掃描模式。使用這種掃描模式的應用程序將被動地偵聽其他掃描結果,而不啟動BLE掃描本身
(2)settingBuilder.setMatchMode有兩個參數可以選:
MATCH_MODE_AGGRESSIVE: 信號弱也會報告
MATCH_MODE_STICKY: 信號比較強和毀兆虧掃描到的次數比較多才會報告
(3)settingBuilder.setCallbackType也有其他參數可選,但適用的就一個
(4) ScanFilter 的過濾方法有幾個,如下圖,打勾的是測試了可行的,但只有第一個DeviceAddress有唯一性