BTLE Example

It is mandatory­­ that you are working with a device supports API 18 or higher.

AndroidManifest.xml
Declare the following permission in manifest file.

uses-feature android:name=”android.hardware.bluetooth_le” android:required=”true”

uses-permission android:name=”android.permission.BLUETOOTH”
uses-permission android:name=”android.permission.BLUETOOTH_ADMIN”
uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION”
uses-permission android:name=”android.permission.ACCESS_COARSE_LOCATION”

How to ­­Get BluetoothAdapter and Enable?

BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
if (bluetoothAdapter != null && !bluetoothAdapter.isEnabled()){
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
}

How to discover Devices?

It is an Asynchronous Process.
Device discover method are different for Pre Lollipop and Post Lollipop,So In your code you have to handle that.

How to do in Pre Lollipop?

BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter  bluetoothAdapter = bluetoothManager.getAdapter();
This Method will get called whenever a new device is discovered.
BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {

    @Override

    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
 runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
};

For Starting and cancelling Discovery use

bluetoothAdapter.startLeScan(leScanCallback);
bluetoothAdapter.stopLeScan(leScanCallback);

How to do in Post Lollipop?

BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
 
ScanCallback scanCallback = new ScanCallback() {

    @Override

    public void onScanResult(int callbackType, ScanResult result) {

    }



    @Override

    public void onBatchScanResults(List results) {

            }



    @Override

    public void onScanFailed(int errorCode) {

        Log.i(TAG ,"onScanFailed "+ errorCode);

    }

};
For Starting and cancelling Discovery use
bluetoothLeScanner.startScan(filters,settings,scanCallback);
where  
ScanSettings settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
List filters = new ArrayList();
bluetoothLeScanner.stopScan(scanCallback);

How to Create BluetoothGattCallback?

Once you found expected bluetooth device,It is time to initiate connection using

BluetoothGatt mBluetoothGatt=bluetoothDevice.connectGatt(this,false,mGattCallback);

What is BluetoothGattCallback?

  • Public API for the Bluetooth GATT Profile.
  • This class provides Bluetooth GATT functionality to enable communication between Bluetooth Smart and Bluetooth Smart ready devices.
  • To connect to a remote peripheral device,Create BluetoothGattCallback and call
    bluetoothDevice.connectGatt(this,false,BluetoothGattCallback) to get instance of this class;
BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

    @Override

    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
//Called when a device connects or disconnects.

    }



    @Override

    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
//Called after client initiates BluetoothGatt.discoverServices()

    }



@Override

 public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
//Called when client calls //BluetoothGatt.readCharacteristic(BluetoothGattCharacteristic characteristic);


     

 }


    @Override

    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
//Called when you perform a read or write characteristic operation.

    }

};

Discover Services and Characteristics

        • Once the connection success, BluetoothGattCallback.onConnectionStateChange() will be called with the newState argument set to BluetoothProfile.STATE_CONNECTED
    • After this , BluetoothGatt.discoverServices() can be called.When the device responds, you will receive the callback BluetoothGattCallback.onServicesDiscovered()
List services = bluetoothGatt.getServices();
for (BluetoothGattService service : services) {
         List characteristics = service.getCharacteristics();
}

Notes:

It is always recommended to stop the scan once you found expected device because discovery process will drain android device’s battery.

How to Configure Descriptor?

From characteristic,try to get Descriptor using CLIENT_CHARACTERISTIC_CONFIG()
where CLIENT_CHARACTERISTIC_CONFIG = “00002902-0000-1000-8000-00805f9b34fb”;

Example:

BluetoothGattDescriptor bluetoothGattDescriptor = characteristic.getDescriptor(
UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
bluetoothGattDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(bluetoothGattDescriptor);

Receiver Notification:

Whenever GATT server sends notification to the android device, BluetoothGattCallback.onCharacteristicChanged() will be called,Inside this callback you will of data sent by GATT Server.

How to Disconnect & Close GATT Client?

BluetoothGatt.disconnect();
BluetoothGatt.close();

Example ::

Basic functionalities of BLE is available in this Github code
https://github.com/kavidriod/BluetoothLowEnergy_Basics

Output:

ble