Android4.3 藍芽BLE初步(收藏)
阿新 • • 發佈:2018-11-19
http://www.blogjava.net/zh-weir/archive/2013/12/09/407373.html
Android4.3 藍芽BLE初步
一、關鍵概念:
Generic Attribute Profile (GATT) 通過BLE連線,讀寫屬性類小資料的Profile通用規範。現在所有的BLE應用Profile都是基於GATT的。 Attribute Protocol (ATT) GATT是基於ATT Protocol的。ATT針對BLE裝置做了專門的優化,具體就是在傳輸過程中使用盡量少的資料。每個屬性都有一個唯一的UUID,屬性將以characteristics and services的形式傳輸。 Characteristic 二、角色和職責:
Android裝置與BLE裝置互動有兩組角色:
中心裝置和外圍裝置(Central vs. peripheral);
GATT server vs. GATT client.
Central vs. peripheral:
中心裝置和外圍裝置的概念針對的是BLE連線本身。Central角色負責scan advertisement。而peripheral角色負責make advertisement。
GATT server vs. GATT client:
這兩種角色取決於BLE連線成功後,兩個裝置間通訊的方式。
舉例說明:
現有一個活動追蹤的BLE裝置和一個支援BLE的Android裝置。Android裝置支援Central角色,而BLE裝置支援peripheral角色。建立一個BLE連線需要這兩個角色都存在,都僅支援Central角色或者都僅支援peripheral角色則無法建立連線。
當連線建立後,它們之間就需要傳輸GATT資料。誰做server,誰做client,則取決於具體資料傳輸的情況。例如,如果活動追蹤的BLE裝置需要向Android裝置傳輸sensor資料,則活動追蹤器自然成為了server端;而如果活動追蹤器需要從Android裝置獲取更新資訊,則Android裝置作為server端可能更合適。
三、許可權及feature:
和經典藍芽一樣,應用使用藍芽,需要宣告BLUETOOTH許可權,如果需要掃描裝置或者操作藍芽設定,則還需要BLUETOOTH_ADMIN許可權:
<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: // 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();
}
四、啟動藍芽:
在使用藍芽BLE之前,需要確認Android裝置是否支援BLE feature(required為false時),另外要需要確認藍芽是否開啟。 如果發現不支援BLE,則不能使用BLE相關的功能。如果支援BLE,但是藍芽沒開啟,則需要開啟藍芽。 開啟藍芽的步驟: 1、獲取BluetoothAdapter BluetoothAdapter是Android系統中所有藍芽操作都需要的,它對應本地Android裝置的藍芽模組,在整個系統中BluetoothAdapter是單例的。當你獲取到它的示例之後,就能進行相關的藍芽操作了。 獲取BluetoothAdapter程式碼示例如下: // Initializes Bluetooth adapter.final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter(); 注:這裡通過getSystemService獲取BluetoothManager,再通過BluetoothManager獲取BluetoothAdapter。BluetoothManager在Android4.3以上支援(API level 18)。 2、判斷是否支援藍芽,並開啟藍芽 獲取到BluetoothAdapter之後,還需要判斷是否支援藍芽,以及藍芽是否開啟。 如果沒開啟,需要讓使用者開啟藍芽: private BluetoothAdapter mBluetoothAdapter;
...
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
五、搜尋BLE裝置:
通過呼叫BluetoothAdapter的 startLeScan()搜尋BLE裝置。呼叫此方法時需要傳入BluetoothAdapter.LeScanCallback
引數。
因此你需要實現
BluetoothAdapter.LeScanCallback
介面,BLE裝置的搜尋結果將通過這個callback返回。
由於搜尋需要儘量減少功耗,因此在實際使用時需要注意:
1、當找到對應的裝置後,立即停止掃描;
2、不要迴圈搜尋裝置,為每次搜尋設定適合的時間限制。避免裝置不在可用範圍的時候持續不停掃描,消耗電量。
搜尋的示例程式碼如下:
/**
* Activity for scanning and displaying available BLE devices.
*/
public class DeviceScanActivity extends ListActivity {
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
...
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
...
}
...
} 如果你只需要搜尋指定UUID的外設,你可以呼叫
startLeScan(UUID[], BluetoothAdapter.LeScanCallback)
方法。
其中UUID陣列指定你的應用程式所支援的GATT Services的UUID。
BluetoothAdapter.LeScanCallback的實現示例如下:
private LeDeviceListAdapter mLeDeviceListAdapter;
...
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
}; 注意:搜尋時,你只能搜尋傳統藍芽裝置或者BLE裝置,兩者完全獨立,不可同時被搜尋。