1. 程式人生 > >Android藍芽使用(二)

Android藍芽使用(二)

轉載自:

https://blog.csdn.net/duo_shine/article/details/70259928

藍芽使用(一)http://blog.csdn.net/duo_shine/article/details/70257113 
藍芽韌體升級:http://blog.csdn.net/duo_shine/article/details 
封裝的一個BleDemo:非常簡單幾行程式碼即可呼叫,如何使用在github寫的也很詳細:https://github.com/duoshine/BlueToothConnect-master

能get到的:

認識藍芽
瞭解藍芽4.0
如何開啟藍芽
如何掃描周邊藍芽裝置
如何連線藍芽裝置
手機端如何與ble終端通訊
五,如何連線藍芽裝置 
上一篇我們已經拿到了藍芽裝置列表,接下來就是連線ble終端了 
首先停止掃描

mBluetoothAdapter.stopLeScan(mLeScanCallback);
1
然後釋放建立連線請求,進行下一個裝置連線請求

public void disconnect() {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        mBluetoothGatt.disconnect();
    }

連線address就是ble終端的mac地址

BluetoothDevice device=mBluetoothAdapter.getRemoteDevice(address);
//直接連線到裝置傳入false
mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback);

mGattCallback是已經連線上裝置,對裝置的某些操作後返回的結果。返回中央的狀態和周邊提供的資料,這個抽象類就9個方法, 
根據你需求實現吧

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status,
                int newState) {
        //與ble終端連線狀態發生變化時
        //STATE_DISCONNECTED 斷開
        //STATE_CONNECTING 連線中
        //STATE_CONNECTED 連線
        //STATE_DISCONNECTING 斷開中
        //連線成功
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                 //        搜尋連線裝置所支援的service  需要連線上才可以
        gatt.discoverServices();
            //斷開連線
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {

            }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        //搜尋服務
          findService(gatt.getServices());
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                BluetoothGattCharacteristic characteristic, int status) {
           // 從藍芽裝置讀取資訊
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                BluetoothGattCharacteristic characteristic) {
    //傳送指令成功後   

        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
        {
            super.onCharacteristicWrite(gatt, characteristic, status);
    //寫入成功
        }
    };

到這裡可以連線ble終端成功了,在這個onConnectionStateChange方法中根據狀態判斷是否連線,斷開的資訊,接下來就是通訊了 
接下來你需要和硬體工程師配合好,不管你做的是什麼ble終端裝置,他必定有相關協議,先了解一下UUID,UUID是ble終端service,characteristic,descriptor的唯一標識, 
上面的搜尋服務方法,需要用到UUID

public void findService(List<BluetoothGattService> paramList) {
        Iterator localIterator1 = paramList.iterator();
        while (localIterator1.hasNext()) {
            BluetoothGattService localBluetoothGattService = (BluetoothGattService) localIterator1
                    .next();
            //根據唯一標識uuid去找到我們需要用到的那個service  service uuid
            if (localBluetoothGattService.getUuid().toString()
                    .equalsIgnoreCase(ConstantUtils.UUID_SERVER)) {
                //拿到該服務中的所有Characteristics
                List localList = localBluetoothGattService.getCharacteristics();
                Iterator localIterator2 = localList.iterator();
                while (localIterator2.hasNext()) {
                    BluetoothGattCharacteristic localBluetoothGattCharacteristic = (BluetoothGattCharacteristic) localIterator2
                            .next();
                    //根據uuid拿到我們需要用到的Characteristics  通知 uuid
                    if (localBluetoothGattCharacteristic.getUuid().toString()
                            .equalsIgnoreCase(ConstantUtils.UUID_NOTIFY)) {
                        bleGattCharacteristic = localBluetoothGattCharacteristic;
                        break;
                    }
                }
                break;
            }
        }
        //  設定為true啟用該通知物件
        mBluetoothGatt.setCharacteristicNotification(bleGattCharacteristic, true);
    }

上面用到了兩個uuid 分別是service的和notification的,還有一個write的,這個不固定,可能你的協議上只有兩個uuid,通知和寫用的是同一個uuid 
接下來就是傳送指令給ble終端了,一般協議規定都是傳送byte[],資料格式要嚴格按照協議規定來寫,比如加密/解密,效驗,分包,長度等等

六,傳送指令至ble終端

public boolean write(byte byteArray[]) {
        if (mBluetoothGatt == null) {
            return false;
        }
        BluetoothGattCharacteristic writeCharacteristic = getCharcteristic(ConstantUtils.UUID_SERVER, ConstantUtils
                .UUID_WRITE);  //這裡用到了寫的uuid 
        if (writeCharacteristic == null) {

            return false;
        }
        writeCharacteristic.setValue(byteArray);
        return mBluetoothGatt.writeCharacteristic(writeCharacteristic);
    }

private BluetoothGattCharacteristic getCharcteristic(String serviceUUID, String characteristicUUID) {
        //得到服務物件
        BluetoothGattService service = getService(UUID.fromString(serviceUUID));  //呼叫上面獲取服務的方法
        if (service == null) {
            return null;
        }
        //得到此服務結點下Characteristic物件
        final BluetoothGattCharacteristic gattCharacteristic = service.getCharacteristic(UUID.fromString
                (characteristicUUID));
        if (gattCharacteristic != null) {
            return gattCharacteristic;
        } else {

            return null;
        }
    }

//根據uuid拿到
  public BluetoothGattService getService(UUID uuid) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            return null;
        }
        return mBluetoothGatt.getService(uuid);
    }

看下getService的原始碼

    public BluetoothGattService getService(UUID uuid) {
        for (BluetoothGattService service : mServices) {
            if (service.getDevice().equals(mDevice) &&
                service.getUuid().equals(uuid)) {
                return service;
            }
        }

        return null;
    }

遍歷了這個mServices集合如果service的uuid相同就返回這個BluetoothGattService ,同樣的看下getCharacteristic的原始碼, 根據寫的uuid拿到BluetoothGattCharacteristic ,ok現在就可以使用BluetoothGattCharacteristic 傳送指令至ble終端了

public BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
        for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
            if (uuid.equals(characteristic.getUuid()))
                return characteristic;
        }
        return null;
    }

到這裡傳送指令成功write返回true,否則取反,如果失敗了的話,可能你的uuid使用錯誤,比如寫的uuid用成了讀的,傳送的資料前面已經提過,根據你的協議來定的,不清楚就多和硬體工程師溝通

接收藍芽返回的資料 
藍芽成功收到我們傳送的指令後,onCharacteristicChanged該方法會收到藍芽返回的資料,

 @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {                               
            byte[] arrayOfByte = characteristic
                    .getValue();
}

Ok,拿到這個陣列該幹啥幹啥吧,有什麼錯誤希望指出,共同學習

demo:https://github.com/duoshine/BlueToothConnect-master