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