基礎準備
藍牙通信概念
通常意義的藍牙通信的含義就是Client通過藍牙對接后進行數據通信,這里面需要注意的是藍牙通信是點對點的,所以是1對1關系,所以就有了Central vs. peripheral (中心設備vs外圍設備)的概念,接下來我們將以Client角度闡述
藍牙通信首先要了解幾個重要的類
BluetoothAdapter
藍牙通信的核心類,單例模式,通過BluetoothAdapter.getDefaultAdapter()獲得或者通過藍牙服務獲取
BluetoothDevice
對應可搜索到的藍牙設備,可使用這個類進行連接
BluetoothGatt
連接成功后的返回,可用來關閉連接,發現服務等等
具體開發流程(代碼)
1.首先需要檢查權限
<uses-featureandroid:name="android.hardware.bluetooth_le"android:required="true"/>
<uses-permissionandroid:name="android.permission.BLUETOOTH"/>
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>
2.檢查ble支持
f(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this,R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
3.獲取藍牙代理
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
或者
BluetoothManager bm = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bm.getAdapter();
4.檢查藍牙是否開啟
if(!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()){
Intent enableBtIntent = newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
5.搜索藍牙設備
mHandler.postDelayed(newRunnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
這里需要注意的是因為藍牙搜索比較費電,所以我們過一個時間間隔就關閉它,
startLeScan(UUID[], BluetoothAdapter.LeScanCallback)有個重載可通過uuid搜索指定的設備
privateBluetoothAdapter.LeScanCallback mLeScanCallback =
newBluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(finalBluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
一旦搜索到設備就加到顯示列表
6.獲取到需要連接的device后連接
BluetoothGatt mBluetoothGatt = device.connectGatt(this, false,BluetoothGattCallback);
這個GattCallback有9個回調,主要提供狀態變換后的數據通信,BluetoothGatt 用來可用來寫數據
可以看源碼大致了解函數功能
7.連接后,就可以通訊了
BLE的三部分Service,Characteristic,Descriptor,所以大致講下這幾個概念
Service
Characteristic的集合。比如心率可以分成好幾個Characteristic來秒速他
Characteristic
一個數據類型,包含一個value和0-n個對value的Descriptor
Descriptor
對Characteristic的描述,比如返回,單位
這三者的查找都是通過uuid,然后通過獲取相應的類進行操作
寫數據
首先需要一個Characteristic對象,然后往里面放數據,這里我們放入byte[]
Characteristic characteristic=new Characteristic();
characteristic.setValue(byte[] mByte);
bluetoothGatt.writeCharacteristic(characteristic);
這時候就會收到GattCallback里的onCharacteristicWrite回調
讀數據
bluetoothGatt.readCharacteristic(characteristic);
調用此方法后會收到GattCallback的onCharacteristicRead回調,或者數據正常傳過來的情況下此方法也會被回調,通過Characteristic.getValue方法即可收到相應數值
Summarize
流程大概就如上所示,有幾個點需要注意
比如connect需要先discoverServices
還有一些數據轉換的問題,16進制,byte[],十進制,字符串...
本文參考woshasanguo藍牙開發