Android 低功耗藍牙的多設備連接與數據接收,簡單實現

項目的一個功能,藍牙多連接。應用同時連接多個設備,等待接收數據,處理後顯示圖表。

在這之前我沒有搞過藍牙方面的東西,只能從基礎開始邊看邊幹。


最開始不知道,看的是傳統藍牙的連接與傳輸,幾天過後,發現與低功耗藍牙不一樣啊,又針對低功耗藍牙開始找資料。


低功耗藍牙支持的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系統的平板,連接四個很快的。


部分手機/平板是國內廠商定製的,不能搜索到藍牙設備或者不能連接設備,可能的原因是硬件設備沒有對這些廠商進行兼容。






發佈了73 篇原創文章 · 獲贊 61 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章