項目的一個功能,藍牙多連接。應用同時連接多個設備,等待接收數據,處理後顯示圖表。
在這之前我沒有搞過藍牙方面的東西,只能從基礎開始邊看邊幹。
最開始不知道,看的是傳統藍牙的連接與傳輸,幾天過後,發現與低功耗藍牙不一樣啊,又針對低功耗藍牙開始找資料。
低功耗藍牙支持的api最低是18。
基本思路:低功耗藍牙連接分兩種,一種是作爲周邊設備,一種是作爲中心設備。因爲需求是多連接,那我們就按照創建一箇中心設備的做法來處理。
下面先記錄一下,一個低功耗藍牙的連接:
注:因爲程序與硬件是一套設備,所以我不需要掃瞄附近的設備,然後選擇連接,直接拿地址進行連接。
藍牙需要的權限:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
接下來在activity中,不管周邊設備還是中心設備,我們都需要拿到:BluetoothManager和BluetoohAdapter:
//獲取BluetoothManager
BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
//獲取BluetoothAdapter
BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter();
//如果藍牙沒有打開 打開藍牙
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}
然後就是通過上面拿到的adapter得到BluetoothDevice對象:
BluetoothDevice bluetoothDeviceOne = mBluetoothAdapter.getRemoteDevice("D8:B0:4C:BC:C0:83");
注:1.傳入的參數就是你藍牙的地址。
2.假如你需要多連接,那麼這裏就要獲得多個BluetoothDevice對象,通過不同的地址。
然後就是BluetoothGatt對象:
private BluetoothGatt mBluetoothGattOne;
在拿到上面兩個對象後,先校驗gatt對象是否在運行:
//如果Gatt在運行,將其關閉
if (mBluetoothGattOne != null) {
mBluetoothGattOne.close();
mBluetoothGattOne = null;
}
然後就是連接設備,並設置連接的回調:
//連接藍牙設備並獲取Gatt對象
mBluetoothGattOne = bluetoothDeviceOne.connectGatt(MainActivity.this, true, bluetoothGattCallbackOne);
其中,bluetoothGattCallbackOne就是回調:
/**
* 第一個設備 藍牙返回數據函數
*/
private BluetoothGattCallback bluetoothGattCallbackOne = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (status == BluetoothGatt.GATT_SUCCESS) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
setText("設備一連接成功");
//搜索Service
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
setText("設備一連接斷開");
}
}
super.onConnectionStateChange(gatt, status, newState);
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
//根據UUID獲取Service中的Characteristic,並傳入Gatt中
BluetoothGattService bluetoothGattService = gatt.getService(UUID_SERVICE);
BluetoothGattCharacteristic bluetoothGattCharacteristic = bluetoothGattService.getCharacteristic(UUID_NOTIFY);
boolean isConnect = gatt.setCharacteristicNotification(bluetoothGattCharacteristic, true);
if (isConnect){
}else {
Log.i("geanwen", "onServicesDiscovered: 設備一連接notify失敗");
}
super.onServicesDiscovered(gatt, status);
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {//數據改變
super.onCharacteristicChanged(gatt, characteristic);
String data = new String(characteristic.getValue());
Log.i("geanwen", "onCharacteristicChanged: " + data);
}
};
注:1.我的需求就是接收是藍牙發送過來的數據,假如你需要寫入數據,或者其他的功能,在上面的callback中,可以複寫對應的方法。
2.上面onConectionStateChange方法就是連接狀態改變時回調的方法,在其中判斷連接是否成功。
3.上面onServicesDiscovered方法就是在onConectionStateChange連接成功之後,發現該藍牙的服務。
在這裏你可以設置你需要的服務,每個藍牙連接中會有不同的服務,設置你需要的即可。
4.上面我設置了接收數據的服務,其中傳入的幾個常量就是我們低功耗藍牙的服務的固定碼,下面貼個例子:
//藍牙設備的Service的UUID
public final static UUID UUID_SERVICE = UUID.fromString("0003cdd0-0000-1000-8000-00805f9b0131");
//藍牙設備的notify的UUID
public final static UUID UUID_NOTIFY = UUID.fromString("0003cdd1-0000-1000-8000-00805f9b0131");
大家仔細看好,兩個碼是不一樣的,一開始我以爲是一樣的,結果調了好久。
因爲我這個需求是不能先搜索,在連接,然後選擇對應服務的,所以我將這些這些操作都省略,即我提前拿到了這幾個服務的碼。
5.上面回調方法onCharacteristicChanged方法就是來數據了,接收的方法。
連接一個低功耗藍牙並接收數據上面就介紹完了,下面說下連接兩個或者多個。
到這裏是後期來修改的,原來簡單的通過上面的連接一個,多次創建對應的對象來實現多連接。
那樣第一個代碼量有點大,重複工作做的多。性能還不是很好。
下面我在github找到一個框架,大神封裝的模塊,clone到本地看他的代碼,學習一番,
下面貼出地址:
具體使用,他的文檔中記錄的很詳細了
學習思路之後自己也封裝一下。
實現多連接過程中遇到了幾個問題,這裏記錄下。
當你的業務需求需要連接多個設備的時候,
需要考驗你的手機/平板的設備了,(價錢高一些性能好一些)
我試用的華爲6.0的平板,同時連接三個是相對穩定一些,一次搜索並連接三個,第四個設備需要重新搜索才能成功。
小米的7.0系統的平板,連接四個很快的。
部分手機/平板是國內廠商定製的,不能搜索到藍牙設備或者不能連接設備,可能的原因是硬件設備沒有對這些廠商進行兼容。