Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bluetooth LE peripheral stop advertising on connect with Bluetooth LE central device

I want to develop app like Bluetooth LE peripheral device which stop advertising on connect with Bluetooth LE central device and restrict Bluetooth LE peripheral device which connects with multiple Bluetooth LE central.

One Bluetooth LE peripheral device only connect with one Bluetooth LE central at a time. Other Bluetooth LE central device could not scan after successfully connection of Bluetooth LE peripheral and Bluetooth LE central

Till now i try below code:

private final BluetoothGattServerCallback mGattServerCallback = new BluetoothGattServerCallback() {

        @Override
        public void onServiceAdded(int status, BluetoothGattService service) {
                                                                                                            super.onServiceAdded(status, service);
        }

        @Override
        public void onConnectionStateChange(BluetoothDevice device, final int status, int newState) {
            super.onConnectionStateChange(device, status, newState);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (newState == BluetoothGatt.STATE_CONNECTED) {
                    mBluetoothDevices.add(device);

                    // Bluetooth LE peripheral stop advertising on connect with Bluetooth LE central device
                    mAdvertiser.stopAdvertising(mAdvCallback);

                    Log.v(TAG, "Connected to device: " + device.getAddress());
                } else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
                    mBluetoothDevices.remove(device);
                    Log.v(TAG, "Disconnected from device");
                }
            } else {
                mBluetoothDevices.remove(device);
                // There are too many gatt errors (some of them not even in the documentation) so we just
                // show the error to the user.
                final String errorMessage = getString(R.string.status_errorWhenConnecting) + ": " + status;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_LONG).show();
                    }
                });
                Log.e(TAG, "Error when connecting: " + status);
            }
        }

        @Override
        public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset,
                                                BluetoothGattCharacteristic characteristic) {
        }

        @Override
        public void onNotificationSent(BluetoothDevice device, int status) {
            super.onNotificationSent(device, status);
            Log.v(TAG, "Notification sent. Status: " + status);
        }

        @Override
        public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
                                                 BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
        }

        @Override
        public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
                                             BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded,
                                             int offset,
                                             byte[] value) {
        }
    };

I am stopAdvertising on connect with BLE central device mAdvertiser.stopAdvertising(mAdvCallback);

It is disconnect connection.

Please help me in this use case. THANKS IN ADVANCE

like image 461
Palak Avatar asked Dec 16 '16 12:12

Palak


People also ask

What is Bluetooth LE advertising?

Bluetooth Low Energy (also sometimes called Bluetooth Smart) has two ways of communicating. The first one is using advertisements, where a BLE peripheral device broadcasts packets to every device around it. The receiving device can then act on this information or connect to receive more information.

How do I advertise Android as a Bluetooth LE peripheral?

To start advertising over Bluetooth LE, you need to retrieve the BluetoothLeAdvertiser from the Android BluetoothAdapter . You can do this in the advertise() method that is called when the advertising button is tapped. BluetoothLeAdvertiser advertiser = BluetoothAdapter.

What are Bluetooth LE devices?

Bluetooth Low Energy is a power-conserving variant of Bluetooth personal area network (PAN) technology, designed for use by Internet-connected machines and appliances. Also marketed as Bluetooth Smart, Bluetooth LE was introduced in the Bluetooth 4.0 specification as an alternative to Bluetooth Classic.


1 Answers

Put BluetoothGattServer.connect(BluetoothDevice device, boolean autoConnect) in BluetoothGatt.STATE_CONNECTED before stopAdvertising, because expected Android framework behavior. If you need to continue to hold the link and don't want to advertise anymore, you need to call into additional connect()

Code snippet of Solution

//******************* SOLUTION **************************
        BluetoothDevice mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getAddress());
        mGattServer.connect(mDevice, false);
//*******************************************************

Code snippet of onConnectionStateChange() implementation

@Override
public void onConnectionStateChange(BluetoothDevice device, final int status, int newState) {
    super.onConnectionStateChange(device, status, newState);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        if (newState == BluetoothGatt.STATE_CONNECTED) {
            mBluetoothDevices.add(device);

//******************* SOLUTION **************************
        BluetoothDevice mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getAddress());
        mGattServer.connect(mDevice, false);
//*******************************************************

            // Bluetooth LE peripheral stop advertising on connect with Bluetooth LE central device
            mAdvertiser.stopAdvertising(mAdvCallback);

            Log.v(TAG, "Connected to device: " + device.getAddress());
        } else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
            mBluetoothDevices.remove(device);
            Log.v(TAG, "Disconnected from device");
        }
    } else {
        mBluetoothDevices.remove(device);
        // There are too many gatt errors (some of them not even in the documentation) so we just
        // show the error to the user.
        final String errorMessage = getString(R.string.status_errorWhenConnecting) + ": " + status;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_LONG).show();
            }
        });
        Log.e(TAG, "Error when connecting: " + status);
    }
}
like image 161
Palak Avatar answered Oct 31 '22 02:10

Palak