- The added line is THIS COLOR.
- The deleted line is THIS COLOR.
[labs.beatcraft.com]]~
[[Android]]~
#contents
*1. About BLE (Bluetooth Low Energy) [#y7765074]
>
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.)~
*2. Basic knowledges of BLE communication [#adc02a2b]
>
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.~
&ref(./gatt.png);
** Profile [#n3183b5b]
>
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.~
** Service [#l6a76675]
>
Service shows the functions of Profile.~
Service consists of several nesting Services and several Characteristics.~
** Characteristic [#tc5d1590]
>
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 [#f831458a]
>
Descriptor shows the attribute value, which is used when a characteristic needs the additional information.~
Some Characteristics do NOT contain any Descriptors.~
* 3. BLE on Android [#fb8170f3]
Android 4.3 or above (API Level 18 or greater) supports BLE.~
** Bluetooth Package [#nf593f39]
>
android.bluetooth.*
**BluetoothManager [#fb739711]
>
It manages the functions of Bluetooth.~
It acquires BluetoothAdapter from BluetoothAdapter.~
**BluetoothAdapter [#g5f81df8]
>
It controls Bluetooth set at a mobile device.~
It scans Bluetooth devices.
**BluetoothGatt [#ibcf03c2]
>
It operates GATT profile.~
It manages the search for Services, and the configuration of Descriptor.~
**BluetoothDevice [#e336bbd3]
>
It receives the scanning results of BluetoothAdapter.~
It is the information of Bluet device.~
**BluetoothGattService [#f2608ca1]
>
It is the information of (GATT) Services.
It holds Characteristic (BluetoothGattCharacteristic).
**BluetoothGattCharacteristic [#kc93d4f6]
>
It is the information of Characteristic.~
It holds Descriptor (BluetoothGattDescriptor). Some Characteristics do NOT have Descriptors.~
**BluetoothGattDescriptor [#dc84db56]
>
The information of Descriptor.
* 4. Implementation of BLE on App [#a44fe1c4]
** Permission [#lc3905b5]
>
Please add these tags listed below to Manifest (AndroidManifest.xml) for making BLE effective.~
Configuration for Permission~
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
~
Please add the tag to Manifest for making sure that the API only work with Android devices, which support BLE.~
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
** Initializing [#u1b9a40c]
>
BluetoothManager bluetoothManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
~
**Making BLE effective [#b671573e]
>
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);
}
** Scanning [#g85c27f1]
>
// Stop scanning 10 seconds later.
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);
}
...
}
private LeDeviceListAdapter mLeDeviceListAdapter;
...
// The callback function after device scanning is completed
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() {
String msg = "name =" + device.getName() + ", bondstate = "
+ device.getBondState() + ", address = "
+ device.getAddress() + ", type" + device.getType()
+ ", uuid = " + device.getUuid().toString();
Log.d("Scan", msg);}
});
}
};
** Connecting with a device [#k7158f57]
>
Call BluetoothDevice$connectGatt(), which is returned form onLeScan(), and connect with a device.~
~
BluetoothDevice:
BluetoothGatt connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)
** Implementation of BluetoothGattCallback [#j35c7555]
>
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.
}
...
};
** Reading [#c30fa84b]
>
Since reading is asynchronous, the reading process requires reading request and reading notification.~
~
Execute BluetoothGatt#readCharacteristic().~
The results are returned to BluetoothGattCallBack#onCharacteristicRead().~
*** Reading request [#e1dcd1a3]
>
mBluetoothGatt.readCharacteristic(characteristic);
*** Reading notification [#p354aad6]
>
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// Characteristic is successfully read.
}
}
** Writing [#w78a8d9a]
>
Since writing is asynchronous, the writing process requires writing request and writing notification.~
~
Execute BluetoothGatt#writeCharacteristic()~
The results are returned to BluetoothGattCallBack#onCharacteristicWrite().~
*** Writing request [#a68e81f3]
>
mBluetoothGatt.writeCharacteristic(characteristic);
*** Writing notification [#q71f3ab3]
>
public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// Characteristic is successfully written.
}
}
** Releasing the connection [#y33a1d42]
>
Execute BluetoothGatt#close().
* Connecting multiple devices [#k0d7c1cf]
>
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.~
** Case (Example) [#k352aecc]
>
Connect with Device A, B, and C.
** Processing procedure [#k41fe845]
>
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()
* About demonstration at Embedded Technology 2015 [#h168d52c]
>
Exhibiting a single Android device is connected to 6 BLE devices, demonstrate how to handle these 6 devices with BLE connection.
***Multiple device connection [#p893dfd2]
>
Multiple BLE devices are connected.~
6 devices are connected one by one.~
*** LED light [#sc24d6fb]
>
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.
***Switch [#j748179f]
>
Employing three relays, turn on/off LED lights. It manages LEDs individually or collectively.
***LED color light valve [#sab94637]
>
It controls the color (RGB) of LED color light valve.
* Revision History [#w5a8e891]
>
- 2016-02-19 This article is initially released.