BLE is the abbreviation of Bluetooth Low Energy and a part of Bluetooth 4.0 standard.
Technical Overview:
Ultra-low power consumption (being capable of operating more than a year in a button battery.)
No compatibility with the previous version of Bluetooth (Classic Bluetooth)
Communication distance is 2.5m to 10m.
A single BLE unit does not have restrictions on the number of concurrent connections. (Classic Bluetooth allows a single unit to connect with 7 units at most.)
In the communication of BLE, GATT (Generic Attribute Profile), a client-server model, is employed.
A device (server) consists of Profile (GATT), Service, Characteristic, and Descriptor. The diagram below describes the design of model.
GATT (Generic Attribute Profile) is a theoretical design for data communication between BLE devices.~ This handles to read the data structure, to write data, and to notify the change in data.
GATT consists of three elements, such as Service, Characteristic, and Descriptor.
Profile does have more than one Service.
Characteristic does have a single value, which indicate its attribute.
It consists of own value, property, which defines how to access the value, and several Descriptors.
Descriptor shows the attribute value, which is used when a characteristic needs the additional information.
Some Characteristics do NOT contain any Descriptors.
As the app is executed, this checks whether Bluetooth function is available or not, If BLE is not effective, a dialog appears for confirmation to make BLE effective.
BluetoothManager bluetoothManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
return false;
}
// Checking Bluetooth function effective or not. If it is not effective, a dialog appears for confirmation to enable BLE
if (mBluetoothAdapter.isEnabled()) {
// Bluetooth is effective
} else {
// Bluetooth is NOT enabled, and the confirmation dialog appears.
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(enableBtIntent, 1);
}
private final BluetoothGattCallback callback = new BluetoothGattCallback() {
// This is executed when the status of connection is changed.
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
// It is connected
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.i(TAG, "Connected to GATT server.");
// Searching for Services
Log.i(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices());
// It is disconnected.
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.i(TAG, "Disconnected from GATT server.");
}
}
@Override
// Return the search results of Services
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
// Success
if (status == BluetoothGatt.GATT_SUCCESS) {
// Acquire the list of Services.
List<BluetoothGattService> gattService = getSupportedGattServices(address);
for(BluetoothGattService service : gattService) {
UUID uuid = service.getUuid();
// Acquire the list of Characteristics from Services.
List<BluetoothGattCharacteristic> charastics = service.getCharacteristics();
// Set up Characteristic for a reception request of Notification
for(BluetoothGattCharacteristic charastic : charastics) {
//
gatt.setCharacteristicNotification(charastic, true);
}
}
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
// Notification for reading
@Override
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// Characteristic is successfully read.
}
}
// Notification for writing
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// Characteristic is successfully written.
}
...
};
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// Characteristic is successfully read.
}
}
public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// Characteristic is successfully written.
}
}
To connect multiple devices, do not connect them simultaneously but connect them one by one.
If the new connection attempt is started before the current connection attempt has been completed, the operation of device becomes unstable.
If the new connection attempt is started before the scanning process is ended, the operation of device also becomes unstable.
1. Connect to Device A
BluetoothDevice#connectGatt()
2. Wait for the results of connection to Device A
BluetoothGattCallback#onConnectionStateChange()
3. Connect to Device B
BluetoothDevice#connectGatt()
4. Wait for the results of connection to Device B
BluetoothGattCallback#onConnectionStateChange()
5. Connect to Device C
BluetoothDevice#connectGatt()
6. Wait for the results of connection to Device C
BluetoothGattCallback#onConnectionStateChange()
There are three LED lights, and each light is capable of shifting six different brightness.
The brightness of LED lights is changed individually or collectively.