在個人上兩篇博文中講解了有關android藍牙的認識以及API的相關的介紹,藍牙BLE的搜索,鏈接以及讀取。
沒有了解的童鞋們請參考:html
目前項目中的效果圖:android
接下來咱們就對藍牙BLE4.0進行一下總結。git
Android ble 藍牙4.0,也就是說API level >= 18,且支持藍牙4.0的手機才能夠使用,若是手機系統版本API level < 18,也是用不了藍牙4.0的哦github
BluetoothGatt api
繼承BluetoothProfile,經過BluetoothGatt能夠鏈接設備(connect),發現服務(discoverServices),並把相應地屬性返回到BluetoothGattCallback bash
BluetoothGattCharacteristic微信
至關於一個數據類型,它包括一個value和0~n個value的描述(BluetoothGattDescriptor) app
BluetoothGattDescriptoride
描述符,對Characteristic的描述,包括範圍、計量單位等 函數
BluetoothGattService
服務,Characteristic的集合。
BluetoothProfile
一個通用的規範,按照這個規範來收發數據。
BluetoothManager
經過BluetoothManager來獲取BluetoothAdapter
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);複製代碼
BluetoothAdapter
一個Android系統只有一個BluetoothAdapter ,經過BluetoothManager 獲取
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
1.8 BluetoothGattCallback複製代碼
已經鏈接上設備,對設備的某些操做後返回的結果。這裏必須提醒下,已經鏈接上設備後的才能夠返回,沒有返回的認真看看有沒有鏈接上設備。
private BluetoothGattCallback GattCallback = new BluetoothGattCallback() {
// 這裏有9個要實現的方法,看狀況要實現那些,用到那些就實現那些
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState){};
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status){};
};
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
BluetoothGatt gatt = device.connectGatt(this, false, mGattCallback);複製代碼
notification對應onCharacteristicChanged
gatt.setCharacteristicNotification(characteristic, true);複製代碼
readCharacteristic對應onCharacteristicRead
gatt.readCharacteristic(characteristic);複製代碼
gatt.wirteCharacteristic(mCurrentcharacteristic);複製代碼
鏈接藍牙或者斷開藍牙 對應 onConnectionStateChange
readDescriptor對應onDescriptorRead;
writeDescriptor對應onDescriptorWrite;
gatt.writeDescriptor(descriptor);複製代碼
gatt.readRemoteRssi()複製代碼
executeReliableWrite對應onReliableWriteCompleted;
discoverServices對應onServicesDiscovered
gatt.discoverServices()複製代碼
<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"/>複製代碼
Android ble 藍牙4.0,也就是說API level >= 18,且支持藍牙4.0的手機才能夠使用,若是手機系統版本API level < 18,也是用不了藍牙4.0的
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "設備不支持藍牙4.0", Toast.LENGTH_SHORT).show();
finish();
}複製代碼
或者是
// 檢查當前手機是否支持blue 藍牙,若是不支持退出程序
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
showToast("不支持藍牙4.0通信");
return;
}
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// 檢查設備上是否支持藍牙
if (mBluetoothAdapter == null) {
showToast("沒有發現藍牙模塊");
return;
}複製代碼
若是本地藍牙處在可用狀態(例如手機藍牙開啓)就返回true
得到藍牙狀態 通常有BluetoothAdapter.STATE_BLE_ON ,STATE_BLE_TURNING_ON ,STATE_BLE_TURNING_OFF ,STATE_OFF
打開藍牙設備,這種方式不友好,建議使用下面方法
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent,OPEN_REQUEST_CODE);複製代碼
這樣會有個彈窗提示用戶是否開啓藍牙
關閉全部的藍牙鏈接後關閉本地藍牙服務
得到藍牙mac地址
得到藍牙名稱,也就收咱們常常設置的藍牙名稱
設置藍牙名稱
開始發現設備(注意是設備,例如另一個手機,而不是藍牙耳機之類的)
獲取綁定(配對)的設備,測試發現只有手動取消綁定才管用,不然即便關閉藍牙,間隔一會再打開,這些仍然是綁定的.
同時一些綁定的設備(例如手環)用這個方法並無返回對應的device
開始對Bluetooth LE devices設備(藍牙耳機,手環,電子稱等)的掃描.回調函數會把掃描到的設備返回,
注意設備會重複被掃描到,最好去掉重複,去重時能夠用mac地址,也能夠用名稱,可是掃描到的Device第一次沒有把
名稱帶回,因此獲取名稱時最好作非空判斷
中止掃描
利用系統默認開啓藍牙對話框
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }複製代碼
Generic Attribute Profile (GATT)—The GATT profile is a general specification for sending and receiving short
pieces of data known as "attributes" over a BLE link. All current Low Energy application profiles are based on
GATT.主從設備都維護了GATT 分別是client 和 server
得到方法,建立鏈接時返回
mConnGatt = bleDevie.connectGatt(this, false, mGattcallback);複製代碼
public abstract class BluetoothGattCallback {
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
}
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
}
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
int status) {
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
}
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
}複製代碼
public boolean setCharacteristicNotification(UUID serviceUuid, UUID characteristicUuid, boolean enable) {
BluetoothGattCharacteristic characteristic = mConnGatt.getService(serviceUuid).getCharacteristic(characteristicUuid);
mConnGatt.setCharacteristicNotification(characteristic, enable);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID);
descriptor.setValue(enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : new byte[]{0x00, 0x00});
return mConnGatt.writeDescriptor(descriptor); // descriptor write
}複製代碼
解決方法:
在廣播中相應的方法裏進行從新鏈接
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {//藍牙已鏈接
tvBluetooth.setText("(已鏈接)");
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
showToast("藍牙鏈接斷開,請重試");
//這裏從新鏈接藍牙
hideLoading();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {//發現藍牙,設置命令
......
} else if(BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { //接收到數據
......
}
}
};複製代碼
有些手性能比較低端,這裏能夠重啓藍牙,進行從新鏈接
首先要保證鏈接藍牙以前,上一次斷開鏈接時的操做:
而後執行:
先中止掃描---》從新掃描---》從新鏈接
上傳數據失敗
把讀取到的數據解析後進行保存在本地,下次上傳的時候一塊兒上傳。上傳成功後記得進行本低數據的清空
注意:BLE藍牙鏈接小設備時通常屬於主從模塊,其中主模塊藍牙能夠同時鏈接多個設備,但讀取時只能讀取一個。
- 主機:可主動搜索從機,能夠發送數據,也能夠接收數據
- 從機:能夠發送數據,也能夠接收數據,但只能被搜索
接下來推薦兩個關於Android藍牙BLE的學習網址:
www.open-open.com/lib/view/op…
若是你以爲此文對您有所幫助,歡迎入羣 QQ交流羣 :232203809
微信公衆號:終端研發部
(歡迎關注學習和交流)