2
votes

I'm writing a BLE app for an open source pedometer and I have it working great so far with one annoying problem: in the BluetoothGattCallback void method "onConnectionStateChange" in the BLE service, the parameter "int newState" can only be one of two values, STATE_DISCONNECTED or STATE_CONNECTED" as documented here:

BluetoothGattCallback docs

Issue is when I disconnect and reattempt to connect to my BLE device, it works, but I have no feedback when it is in a connecting state. The screen remains static and jumps from disconnected to connected and can take anywhere from 3 seconds to 15 to do so.

My question therefore is, can I directly access the onConnectionStateChange method for the BluetoothGattCallback and pass the value for "BluetoothProfile.STATE_CONNECTING" in it so the lines of code in the "else if" statement for the state "STATE_CONNECTING" execute? If so, how?

I've attached my onConnectionStateChange and connect methods. They are mostly unchanged from those provided in the sample heart rate monitor app provided on the developer's website. My only change is the "else if" for the STATE_CONNECTING.

Thanks.

        @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        String intentAction;
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            intentAction = ACTION_GATT_CONNECTED;
            mConnectionState = STATE_CONNECTED;
            broadcastUpdate(intentAction);
            Log.i(TAG, "Connected to GATT server.");
            // Attempts to discover services after successful connection.
            Log.i(TAG, "Attempting to start service discovery:" +
                    mBluetoothGatt.discoverServices());
        } 
        else if (newState == BluetoothProfile.STATE_CONNECTING) {
            intentAction = ACTION_GATT_CONNECTING;
            mConnectionState = STATE_CONNECTING;
            Log.i(TAG, "Attempting to connect to GATT server...");
            broadcastUpdate(intentAction);
        }
        else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            intentAction = ACTION_GATT_DISCONNECTED;
            mConnectionState = STATE_DISCONNECTED;
            Log.i(TAG, "Disconnected from GATT server.");
            broadcastUpdate(intentAction);
        }

    }

    public boolean connect(final String address) {
    if (mBluetoothAdapter == null || address == null) {
        Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
        return false;
    }

    // Previously connected device.  Try to reconnect.
    if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
            && mBluetoothGatt != null) {
        Log.i(TAG, "Trying to use an existing mBluetoothGatt for connection.");
        if (mBluetoothGatt.connect()) {
            mConnectionState = STATE_CONNECTING;
            return true;
        } else {
            return false;
        }
    }

    final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
    if (device == null) {
        Log.w(TAG, "Device not found.  Unable to connect.");
        return false;
    }
    // We want to directly connect to the device, so we are setting the autoConnect
    // parameter to false.
    mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
    Log.i(TAG, "Trying to create a new connection.");
    mBluetoothDeviceAddress = address;
    mConnectionState = STATE_CONNECTING;
    return true;
}
1

1 Answers

1
votes

Turns out all I needed to do was call the Gatt callback myself and create a private static int to pass to the callback method.

mGattCallback.onConnectionStateChange(mBluetoothGatt, GATT_INDETERMINATE, STATE_CONNECTING);

where GATT_INDETERMINATE is

private static int GATT_INDETERMINATE = 8;

I made sure the BluetoothGattCallback class didn't make use of 8, so 8 is a fine value to use. Finally in the onConnectionStateChanged I do the following and broadcast the appropriate intent with identifying action string.

    else if (newState == BluetoothProfile.STATE_CONNECTING) {
            intentAction = ACTION_GATT_CONNECTING;
            mConnectionState = STATE_CONNECTING;
            Log.i(TAG, "Attempting to connect to GATT server...");
            broadcastUpdate(intentAction);
        }