Android Open Source - AndroidBleLib Ble Heart Service

From Project

Back to project page AndroidBleLib.


The source code is released under:

MIT License

If you think the Android project AndroidBleLib listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package io.hearty.ble.lib.heart;
/*from w ww .  j a  v a  2s .c o m*/
import android.bluetooth.*;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import io.hearty.ble.lib.BleScanner;
import io.hearty.ble.lib.utils.BlePrefs;
import io.hearty.ble.lib.utils.SampleGattAttributes;
import io.hearty.witness.Reporter;
import io.hearty.witness.Witness;

import java.util.HashMap;
import java.util.List;
import java.util.UUID;

public class BleHeartService extends Service implements Reporter {
    // A service that interacts with the BLE device via the Android BLE API.
    private final static String TAG = "BleHeartService";
    private Handler handler = new Handler();

    private BluetoothGatt mBluetoothGatt;

    public final static String ACTION_GATT_CONNECTED =
    public final static String ACTION_GATT_DISCONNECTED =
    public final static String ACTION_GATT_SERVICES_DISCOVERED =
    public final static String ACTION_DATA_AVAILABLE =

    public static String UUID_HEART_RATE_MEASUREMENT =

    private BleScanner scanner;
    private BlePrefs prefs;

    public static boolean isRunning = false;

    public void onCreate() {
        isRunning = true;

        scanner = new BleScanner(getApplicationContext());
        prefs = new BlePrefs(this);

        Witness.register(BleConnect.class, this);

    public int onStartCommand(Intent intent, int flags, int startId) {
        isRunning = true;

        if (!reconnectLeDevice())

        return super.onStartCommand(intent, flags, startId);

    public void onDestroy() {
        isRunning = false;

        Witness.remove(BleConnect.class, this);

        if (null != scanner)

        if (null != mBluetoothGatt) {


    private void connectLeDevice(BluetoothDevice device) {
        mBluetoothGatt = device.connectGatt(BleHeartService.this, true, mGattCallback);
        Log.d(TAG, "connecting to " + device.getAddress());

        // remember the device you're connecting to

        // stop scanning

    private boolean reconnectLeDevice() {
        BluetoothDevice device = prefs.getConnectedDevice();
        if (null != device) {
            return true;
        return false;

    // Various callback methods defined by the BLE API.
    private final BluetoothGattCallback mGattCallback =
            new BluetoothGattCallback() {
                public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                                    int newState) {
                    String intentAction;
                    if (newState == BluetoothProfile.STATE_CONNECTED) {
                        intentAction = ACTION_GATT_CONNECTED;
                        Log.i(TAG, "Connected to GATT server.");
                        Log.i(TAG, "Attempting to start service discovery:" +

                    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                        intentAction = ACTION_GATT_DISCONNECTED;
                        Log.i(TAG, "Disconnected from GATT server.");

                // New services discovered
                public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                    } else {
                        Log.w(TAG, "onServicesDiscovered received: " + status);

                // Result of a characteristic read operation
                public void onCharacteristicRead(BluetoothGatt gatt,
                                                 BluetoothGattCharacteristic characteristic,
                                                 int status) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);

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


    public IBinder onBind(Intent intent) {
        return null;

    private void broadcastUpdate(final String action) {
        broadcastUpdate(action, null);

    private void broadcastUpdate(final String action,
                                 final BluetoothGattCharacteristic characteristic) {

        Log.d(TAG, "broadcastUpdate");

        if (ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            // Show all the supported services and characteristics on the
            // user interface.

        if (null == characteristic)

        // This is special handling for the Heart Rate Measurement profile. Data
        // parsing is carried out as per profile specifications.
        if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid().toString())) {
            int flag = characteristic.getProperties();
            int format;
            if ((flag & 0x01) != 0) {
                format = BluetoothGattCharacteristic.FORMAT_UINT16;
                Log.d(TAG, "Heart rate format UINT16.");
            } else {
                format = BluetoothGattCharacteristic.FORMAT_UINT8;
                Log.d(TAG, "Heart rate format UINT8.");
            final HeartRate heartRate = new HeartRate(characteristic.getIntValue(format, 1));
            Log.d(TAG, String.format("Received heart rate: %d", heartRate.getHeartRate()));
        } else {
            // For all other profiles, writes the data formatted in HEX.
            final byte[] data = characteristic.getValue();
            if (data != null && data.length > 0) {
                final StringBuilder stringBuilder = new StringBuilder(data.length);
                for (byte byteChar : data)
                    stringBuilder.append(String.format("%02X ", byteChar));
                Log.d(TAG, "new value " + stringBuilder.toString());

    // Demonstrates how to iterate through the supported GATT
    // Services/Characteristics.
    // In this sample, we populate the data structure that is bound to the
    // ExpandableListView on the UI.
    private void registerHeartRate(List<BluetoothGattService> gattServices) {
        if (gattServices == null)

        Log.d(TAG, "registerHeartRate list size: " + gattServices.size());

        // Loops through available GATT Services.
        for (BluetoothGattService gattService : gattServices) {
            String uuid = gattService.getUuid().toString();
            String service = SampleGattAttributes.lookup(uuid, "unknown service");

            List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
            // Loops through available Characteristics.
            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                HashMap<String, String> currentCharaData = new HashMap<String, String>();
                String cUuid = gattCharacteristic.getUuid().toString();

                if (UUID_HEART_RATE_MEASUREMENT.equals(cUuid)) {
                    Log.d(TAG, String.format("charactersitics for %s: %s", cUuid, SampleGattAttributes.lookup(cUuid, "unknown characteristic")));
                    mBluetoothGatt.setCharacteristicNotification(gattCharacteristic, true);
                    BluetoothGattDescriptor descriptor = gattCharacteristic.getDescriptor(


    public void notifyEvent(final Object o) { Runnable() {
            public void run() {

                if (o instanceof BleConnect) {
                    connectLeDevice(((BleConnect) o).device);


Java Source Code List