BLE

android4.3 nei內置了ble併爲上層app提供相應的接口來使用BLE功能。html

 

BLE主要涉及的協議及術語:android

 

GenericAttribute Profile (GATT)數組

BLE上層的協議都是基於GATT,它是一個通用的規範,經過BLE鏈接發送/接收屬性值。服務器

 

bluetoothSIG定義了不少的ble協議。app

 

AttributeProtocol (ATT)ide

GATT是創建在ATT之上。也被稱爲GATT/ATT。post

 

ATT運行在ble設備上,因此被優化,儘量的佔用較少的字節。優化

 

每個屬性被指定一個UUID,經過ATT傳輸的屬性被格式化位特性(characteristics)或服務(services)。ui

 

Characteristicthis

一個特性包含一個單一的值和0-n個描述符(Descriptor)來描述這個特性值。一個特性能夠被看做一個類型。

 

Descriptor

描述符被定義爲屬性,這些屬性用來描述特性的值。

例如:規定特性值的取值範圍,特性值的單位等

 

Service

服務是一組特性的集合。例如:「心率檢測」服務包含「心速測量」的特性。

 

角色和職責

中心與外圍:被應用於BLE鏈接自己,中心角色設備掃描/尋找廣播,外圍設備角色發出廣播。

 

GATTserver vs. GATT client:

這個決定了兩個設備在創建鏈接以後如何交互。

 

android手機和BLE設備的區別:手機支持中心角色(centralrole),BLE設備支持peripheralrole。

 

一旦創建鏈接,他們就開始相互傳輸gatt數據,根據傳輸的數據的種類其中的一個可能做爲服務器。

若是BLE設備想報告數據給手機,它可能讓BLE設備的傳感器做爲服務器。若是BLE設備準備接收來自手機的數據,手機的傳感器就做爲服務端。

 

以上例子說明:androidapp 是GATT client,GATTclient 從GATT server 獲取數據。也能夠設計android app 做爲GATTserver。

 

BLE權限:

<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"/>

 

 

若是想把app提供給不支持BLE的設備須要設置android:required="fasle",而後在運行時進行判斷:

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
    Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
    finish();
}

 

 

設置BLE

 

1:獲取BluetoothAdapter

 

BluetoothAdapter是全部藍牙功能所必需的,整個系統只有一個BluetoothAdapter,獲取BluetoothAdapter以後就能夠進行各類藍牙的操做了。

// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager =
        (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();

 

2:啓動藍牙

經過isEnabled()判斷是否啓動,若是沒有啓動,經過下面的方式啓動:

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);
}

 

3:查找BLE設備

經過startLeScan查找LE設備,並實現LeScanCallback做爲參數。

注意事項:1:一旦找到所查找的設備,當即中止掃描

2:設置掃描超時,避免循環掃描。

 

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);
        }
        ...
    }
...
}

 

 

若是須要查找特定類型的LE設備,須要使用startLeScan(UUID[],BluetoothAdapter.LeScanCallback()),提供一個你的設備支持的服務的UUID數組。

 

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,二者不能同時搜索。

 

鏈接GATTserver

使用connectGatt鏈接到BLE設備的GATT server,

mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

 

 

將會返回一個BluetoothGatt實例,經過這個實例能夠進行Gattclient的各類操做。調用者(androidapp)是Gattclient。GattCallback用來提供結果給客戶端。

 

讀取BLE的屬性

若是androidapp已經鏈接了Gatt server而且發現了服務,就可以進行屬性的讀寫了。

 

 

收取Gatt的通知

 

一般BLEapp須要被通知,若是BLE設備的特性發生了改變。

使用setCharacteristicNotification方法爲一個特性設置通知:

private BluetoothGatt mBluetoothGatt;
BluetoothGattCharacteristic characteristic;
boolean enabled;
...
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
...
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
        UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);

 

一旦一個特性被設置爲通知可用,遠端設備的特性發生改變就會觸發onCharacteristicChanged

回調。

@Override
// Characteristic notification
public void onCharacteristicChanged(BluetoothGatt gatt,
        BluetoothGattCharacteristic characteristic) {
    broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}

 

關閉clientapp

結束和BLE設備的通信後,須要釋放資源:

public void close() {
    if (mBluetoothGatt == null) {
        return;
    }
    mBluetoothGatt.close();
    mBluetoothGatt = null;
}
相關文章
相關標籤/搜索