Descriptorandroid
這三部分都用UUID做爲惟一標識符。UUID爲這種格式:0000ffe1-0000-1000-8000-00805f9b34fb。好比有3個Service,那麼就有三個不一樣的UUID與Service對應。這些UUID都寫在硬件裏,咱們經過BLE提供的API能夠讀取到。git
1.先介紹一下關於藍牙4.0中的一些名詞吧:
(1)GATT(Gneric Attibute Profile)程序員
經過ble鏈接,讀寫屬性類小數據Profile通用的規範。如今全部的ble應用Profile 都是基於GATTgithub
(2)ATT(Attribute Protocal) GATT是基於ATT Potocal的ATT針對BLE設備專門作的具體就是傳輸過程當中使用盡可能少的數據,每一個屬性都有個惟一的UUID,屬性chartcteristics and Service的形式傳輸。api
好比。有個藍牙ble的血壓計。他可能包括多個Servvice,每一個Service有包括多個Characteristic數組
注意:藍牙ble只能支持Android 4.3以上的系統 SDK>=18bash
2.如下是開發的步驟:微信
2.1首先獲取BluetoothManagerasync
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>複製代碼
除了藍牙權限外,若是須要BLE feature則還須要聲明uses-feature:<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>複製代碼
按時required爲true時,則應用只能在支持BLE的Android設備上安裝運行;required爲false時,Android設備都可正常安裝運行,須要在代碼運行時判斷設備是否支持BLE feature:ide
// Use this check to determine whether BLE is supported on the device. Then
// you can selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}複製代碼
private BluetoothManager bluetoothManager;
bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();複製代碼
或者是:
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();複製代碼
兩行方式都是能夠的。
注:這裏經過getSystemService獲取BluetoothManager,再經過BluetoothManager獲取BluetoothAdapter。BluetoothManager在Android4.3以上支持(API level 18)。
// 檢查設備上是否支持藍牙
if (mBluetoothAdapter == null) {
showToast("沒有發現藍牙模塊");
return;
}複製代碼
3.開啓藍牙設備
開啓藍牙設備有兩種方式:
第一種直接簡單暴力不給用戶進行提示:
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}複製代碼
第二種直優雅的踐行開啓而且有彈框進行提示,隱式啓動Intent:
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}複製代碼
4.掃描藍牙設備
我這裏是把掃描到的BLE地址存放到List集合中去。這裏咱們能夠寫一個方法進行封裝一下。
/***********
* 掃描設備
********/
private void scanLeDevice(final boolean enable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
if (enable) {
devices.clear();//清空集合
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
}, INTERVAL_TIME);
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
try {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} catch (Exception e) {
}
}
}
}複製代碼
在這個掃描方法中,咱們在AndroidStudio或者是Eclipse中會看到startLeScan方法會有橫線,代表這個方式顯示過時的方法,那麼
若是你只須要搜索指定UUID的外設,你能夠調用 startLeScan(UUID[], BluetoothAdapter.LeScanCallback)方法。
其中UUID數組指定你的應用程序所支持的GATT Services的UUID。
那麼LeScanCallback的初始化代碼以下:
private void initCallBack(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (device != null) {
if (!TextUtils.isEmpty(device.getName())) {
// devices.add(device);
String name = device.getName();
if (name.contains(BluetoothDeviceAttr.OYGEN_DEVICE_NAME)) {
if (!devices.contains(device)) {
devices.add(device);
}
}
}
}
}
});
}
};
} else {
getToast("設備藍牙版本太低");
return;
}
}複製代碼
那麼若是在設備多的狀況下咱們講搜出不少的設備。咱們能夠選擇咱們所須要的地址進行連接。可是這類要注意的是:搜索時,你只能搜索傳統藍牙設備或者BLE設備,二者徹底獨立,不可同時被搜索.
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the autoConnect
// parameter to false.
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);複製代碼
這裏調用的是device的connectGatt方法
/**
* Connect to GATT Server hosted by this device. Caller acts as GATT client.
* The callback is used to deliver results to Caller, such as connection status as well
* as any further GATT client operations.
* The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
* GATT client operations.
* @param callback GATT callback handler that will receive asynchronous callbacks.
* @param autoConnect Whether to directly connect to the remote device (false)
* or to automatically connect as soon as the remote
* device becomes available (true).
* @throws IllegalArgumentException if callback is null
*/
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback) {
return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO));
}複製代碼
api中闡述的是第一個參數是上下文對象Context,第二個參數是是否自動鏈接,第三個是藍牙的GattCallback回調。
private BluetoothGattCallback GattCallback = new BluetoothGattCallback() {
// 這裏有9個要實現的方法,看狀況要實現那些,用到那些就實現那些
//當鏈接狀態發生改變的時候
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState){
};
//回調響應特徵寫操做的結果。
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status){
};
//回調響應特徵讀操做的結果。
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
}
//當服務被發現的時候回調的結果
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
}
當鏈接能被被讀的操做
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
}
......
};複製代碼
鏈接的過程咱們一個經過service來進行鏈接,也能夠在activity中進行操做。
好,到此爲止,一個BLE藍牙鏈接設備的整個流程咱們已經清楚完畢。
可是在實際操做過程當中不免會出現一些比較坑人的問題。好比我用一個地址進行藍牙設備鏈接,偶爾會出現藍牙鏈接不上或者是說鏈接上設備後不返回數據等問題。那麼此時咱們可能會重啓一下藍牙或手機就立馬有成功了。此時咱們千萬不能矇蔽,也不要懷疑本身的人生。這是由於Android4.x的藍牙仍是不太成熟。目前能夠來講是個測試階段。
這個時候咱們怎麼辦呢?
此時不要抱怨什麼,難到咱們做爲Android程序員就註定如此的苦逼嗎?
答案是否認的。
如何去優化呢?那麼咱們就應該從UI界面,用戶體驗上進行操做來實現
能夠在UI上進行對用戶進行相對應的提示
藍牙設備鏈接上手機,正在讀取,提示數據正在讀取中...
咱們不能子在Android系統上來操做什麼,咱們在體驗上作到了咱們能作的就能夠的。
學習參考道demo下載地址:
github.com/androidstar…
學到這裏,關於AndroidBLE藍牙鏈接咱們已經基本上實現了藍牙的搜索,鏈接,讀取等。
你們項目中若是常常涉及到硬件好比手環,溫度計,汗液儀,心電圖,血壓計等這些ble的藍牙設備,就必定會用到藍相關方面的知識。這裏筆者先給你們提早踩一下坑,進行了總結,爲後面的小夥伴在研究藍牙方面儘可能的少踩一些坑。如多對藍牙的歷程還未有清楚的認識,請參考深刻了解Android藍牙Bluetooth4.0——《基礎篇》。
若是你以爲此文對您有所幫助,歡迎入羣 QQ交流羣 :232203809
微信公衆號:終端研發部
(歡迎關注學習和交流)複製代碼