0

I am working on an android application to hook up raspberry pi's to a local wifi network sending them ssid and ssid password information over bluetooth from my android phone. The rpi's are running node servers using bleno.

The set up of my application is as follows.

  1. I scan for ble devices displaying a checklist of devices for the user to select
  2. Once selected the user click button 'next' opening a new activity binding to a new BluetoothLeService.
  3. This activity has a confirm button that when clicked starts the connection process of the ble peripheral to the phone.
  4. Once done sending ssid and ssid_pwd data to the peripheral I tear down and unbind from BluetoothLeService, finish that activity, and then start a success screen activity that routes the user back to the scanning screen to start that process all over again.

So that part is all fine. I can even select multiple peripherals to send data two and that works.

My problem comes after step 4. If a user decides to select another peripheral after they have already done one onServiceConnected is called called for the new peripheral but mBluetoothGatt.discoverServices() seems to pick up two services. Once for the previously connected peripheral and once for the new one.

Note: this only happens when I unbind from the service and then bind again later. Binding once and working with two peripherals seems to work.

What could be causing this? I have checked well over a dozen times that BluetoothLeService is being destroyed, the activity that binding to BluetoothLeService is being destroyed, even checking that the first peripheral isn't broadcasting or accepting ble connections. I have even physically unplugged the first rpi. The btsnoop_hci.log shows connecting to one peripheral and then the other so it has to be within the app code. Does anyone have any ideas?

This is the part of the code that starts the mess.

    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,gatt);
                    Log.i(TAG, "Connected to GATT server.");
                    Log.i(TAG, "Attempting to start service discovery:" +
                            mBluetoothGatt.discoverServices()); // <-- The problem starts here

                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

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

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

                } else {
                    Log.e("ERROR", "Gatt onServiceDiscovered failed. Error code + " + status);
                }
            }
            @Override
            public void onCharacteristicWrite(BluetoothGatt gatt,
                                              BluetoothGattCharacteristic characteristic,
                                              int status) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
                }
                Log.d("DEBUG", characteristic.getValue().toString());
            }
            @Override
            // 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);
                }
                Log.d("DEBUG", characteristic.getValue().toString());
            }
            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt,
                                                BluetoothGattCharacteristic characteristic) {
                Log.d("DEBUG", characteristic.getValue().toString());
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            }


        };

Thanks

luckyging3r
  • 3,047
  • 3
  • 18
  • 37

1 Answers1

0

When one registers a receiver, one must also unregister.

Edit: For anyone getting into android ble the googlesamples/android-BluetoothLeGatt repo on Github is lifeblood.

https://github.com/googlesamples/android-BluetoothLeGatt/tree/master/Application/src/main/java/com/example/android/bluetoothlegatt

luckyging3r
  • 3,047
  • 3
  • 18
  • 37