29 August, 2013

Android BLE development recipes

How to set up BLE:



1. Declare the Bluetooth permission(s) in your application manifest file.
<uses-permission android:name="android.permission.BLUETOOTH"/>
<
uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
BLUETOOTH:
You need this permission to perform any Bluetooth communication, such as requesting a connection, accepting a connection, and transferring data.
BLUETOOTH_ADMIN:
Allow your app to initiate device discovery or manipulate Bluetooth settings


2. Make sure the devices support BLE:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

How to enable Bluetooth LE



private BluetoothAdapter mBluetoothAdapter;


final BluetoothManager bluetoothManager =
               (
BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter
= bluetoothManager.getAdapter();if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
   
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
   startActivityForResult(enableBtIntent,
REQUEST_ENABLE_BT);
}
else {
  process_your_method();
}


protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          
if (requestCode == REQUEST_ENABLE_BT ) {
               
if (resultCode == RESULT_OK) {
              
  //TODO:  add logic if you’d like to  
           }
           
else {
               finish();
                
return;
           }
         
       }
       
super.onActivityResult(requestCode, resultCode, data);
   }




How to add services to GATT server

1, Using BluetoothManager to openGattServer to get Gatt server instance.
2, Initialize a service instance, add the service to Gatt server by calling
addService(BluetoothGattService service)

Not confirmed.

How to advertise services

N/A at this point.


How to find BLE devices



private BluetoothAdapter.LeScanCallback mLeScanCallback =
       
new BluetoothAdapter.LeScanCallback() {
   
@Override
   
public void onLeScan(final BluetoothDevice device, int rssi,
           
byte[] scanRecord) {
           
//TODO: Add your code
       }
};


mBluetoothAdapter.startLeScan(mLeScanCallback);


You can also use the other API:
which allow you to scan with service uuid filters.

I tested this function, failed to detect any devices.


How to get peripheral advertising data:

In BluetoothAdapter.LeScanCallback, you can get advertising data from callback method onLeScan: byte[] scanRecord.


How to connect to GATT server

mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
The caller is the GATT client.


How to operate on Characteristics

  • To read characteristics:
mBluetoothGatt.readCharacteristic(characteristic);
callback method: onCharacteristicRead(BluetoothGatt gatt, int status).
Make sure the characteristic allows to read:
BluetoothGattCharacteristic.PROPERTY_READ
  • To write characteristics:
    mBluetoothGatt.writeCharacteristic(characteristic)
callback method: onCharacteristicRead(BluetoothGatt gatt, int status).
    Make sure the characteristic allows to write:
    BluetoothGattCharacteristic.PROPERTY_WRITE
  • To receive notifications:
    Please refer to How to set up to receive notifcation
callback method: onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
Make sure the characteristic allows to notify:
    BluetoothGattCharacteristic.PROPERTY_NOTIFY



How to set up to receive notification

mBluetoothGatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(               UUID.fromString(“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”));
descriptor
.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt
.writeDescriptor(descriptor);


How to cleanup resources

mBluetoothGatt.close();
mBluetoothGatt = null;


Or
mBluetoothGattServer.close();
mBluetoothGattServer = null;




How to set connection range and RSSI strength filter

During the scan process, when a new BLE devices is detected,
private BluetoothAdapter.LeScanCallback mLeScanCallback =
       
new BluetoothAdapter.LeScanCallback() {
   
@Override
   
public void onLeScan(final BluetoothDevice device, int rssi,
           
byte[] scanRecord) {
           
//TODO: Add your code: if rssi < standard_rssi, then skip this device.
// The range of RSSI should be -100db to 0.  I have to confirm it.
       }
};




How to set scan timeout

Use android.os.Handler


How to get RSSI by interval:

Use Handler and Runnable objects to generate a repeat task to call GATT api by interval:
and in the callback onReadRemoteRssi (BluetoothGatt gatt, int rssi, int status)
to broadcast the RSSI value.


Communicate with iOS devices:

Android to be center mode, 
iOs devices to be peripheral mode.
Able to scan, connection is not stable, services cannot be discovered.
It works now. 
you can scan, connect gatt, discovery services and operate characteristics with iOs devices.