7
votes

I'm using two Android 5.0 devices to communicate through Bluetooth Low Energy and I wan't :

  • Device 1 to act as Central and Server.

  • Device 2 to act as Peripheral and Client.


This is the behavior I'd like to achieve :

1) Device 2 starts advertising (peripheral role).

2) Device 1 starts scanning (central role), and gets the advertising device (BluetoothDevice object) through the ScanCallback's onScanResult method.

3) I now want the advertising device (Device 2) to be notified that it has been scanned and be able to get the BluetoothDevice associated with Device 1.

4) Device 1 has an instance of BluetoothGattServer. Device 2 would now call connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) on Device 1 to get an instance of BluetoothGatt.

5) In the end, Device 1 is Server and Device 2 is Client.


So far I've found that in step 2, once Device 1 holds the BluetoothDevice for Device 2, it can only connect as client like in step 4 using connectGatt.

I might be able to use the BluetoothGattServer defined in Device 1, and call : gattServer.connect(BluetoothDevice device, boolean autoConnect) with device being Device 2.

But how will Device 2 be notified it's been connected to ?

And how will I get an instance of BluetoothGatt in Device 2 if I can't call connectGatt(Context, boolean, BluetoothGattCallback) on a BluetoothDevice?

Thank you in advance for your help !

Some documentation :

BluetoothGattServer

BluetoothDevice

2
Hi Thomas, have you found any solution to your problem?Hollerweger
Hi Hollerweger, unfortunately I never found the solution. It was for a project at university, I ended up demonstrating my work with two phones and explained why it couldn't work with that specific microcontroller. I graduated since and haven't given it any more of my time. However it might be worth checking if anything changed with Android 6. Please let me know if you figure something out! ;)Thomas W

2 Answers

1
votes

1) Device 2 starts advertising (peripheral role).

Peripheral role will advertise, make sure to add CONNECTABLE

     AdvertiseSettings.Builder settingBuilder = new AdvertiseSettings.Builder();
     settingBuilder.setConnectable(true);

And start advertisement accordingly.

2) Device 1 starts scanning (central role), and gets the advertising device (BluetoothDevice object) through the ScanCallback's onScanResult method.

Perfect, now call connectGatt on this device(peripheral), make sure you stops the advertisement after you gets required device, otherwise you will end up sending multiple connect commands.

3) I now want the advertising device (Device 2) to be notified that it has been scanned and be able to get the BluetoothDevice associated with Device 1.

When you calls connectGatt from Central/client role, your peripheral will get a notification in its BluetoothGattServerCallback'onConnectionStateChange.

there you will know that connection has been made. though you have to register gatt Service with characteristics at peripheral side.

4) Device 1 has an instance of BluetoothGattServer. Device 2 would now call connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) on Device 1 to get an instance of BluetoothGatt.

Wrong, Device 1 will initiate connection as I have stated in point 3. both device's onConnectionStateChange will be called to know that connection has been made.

5) In the end, Device 1 is Server and Device 2 is Client.

Wrong, Device 2 is peripheral(Server), Device 1 is Monitor(Client)

0
votes

You must turn it around a bit. The scanner is the one connecting to the advertiser. Dev1 scans dev2 adv and scan response. then dev1 should connect. Dev2 will get callback on connect. There is no callback when someone hear your adv or request scan response on android. Check instead 0x14 «List of 16-bit Service Solicitation UUIDs» from btsig if You want to advertise request for servers with a certain service to connect to You. It is a bit unusual ti see this used.