Search code examples
androidbluetooth-lowenergyandroid-broadcastandroid-service-binding

My Broadcast Receiver does not receive broadcasts from Local Service


I am new to android development and currently I am trying to modify the sample code for Bluetooth LE interfacing found here https://developer.android.com/samples/BluetoothLeGatt/index.html .
This demo project is divided into two activities but I want to reduce it to one activity; the DeviceControlActivity is changed into a 'regular' Java class. After a few attempts I made the BluetoothLeService run with this constructor of my Device Control class:

public DeviceControl (BluetoothDevice device, Context context) {
    mDeviceName = device.getName();
    mDeviceAddress = device.getAddress();
    this.context = context;

    Log.d(TAG, "DeviceControl construktor");
    Log.d(TAG, "Context = " + context);

    Intent gattServiceIntent = new Intent(context, BluetoothLeService.class);
    context.bindService(gattServiceIntent, mServiceConnection, context.BIND_AUTO_CREATE);

}

The BluetoothLeService class is ridden with Log.d()'s and seems to work fine; however, the broadcasts it emits here:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @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_DISCONNECTED) {
            intentAction = ACTION_GATT_DISCONNECTED;
            mConnectionState = STATE_DISCONNECTED;
            Log.i(TAG, "Disconnected from GATT server.");
            broadcastUpdate(intentAction);
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
        } else {
            Log.w(TAG, "onServicesDiscovered received: " + status);
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic,
                                     int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
    }
};

private void broadcastUpdate(final String action) {
    Log.d(TAG, "Methode broadcastUpdate aufgerufen. Action = " + action);
    final Intent intent = new Intent(action);
    sendBroadcast(intent);
}

However, they never arrive in the DeviceControl Class I originally bound the service to:

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "Broadcast received");
        final String action = intent.getAction();
        if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {

        } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {

        } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            // Show all the supported services and characteristics on the user interface.
            System.out.println("GATT-services discovered");
            displayGattServices(mBluetoothLeService.getSupportedGattServices());
        } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
           displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
        }
    }
};

What's wrong here?


Solution

  • I cannot comment yet, but is it registered?

    You have to register the broadcast receiver with the registerReceiver method.

    P.S. If you are using the AppCompat library and do not need the broadcasts to leave your app, also look into the LocalBroadcastManager.