Android bluetooth connections issues - android

I have confusion on bluetooth connections.
Preface: when connecting devices for android over bluetooth you can connect as server or as client
My understand: connecting as the server essentially means that your device will be hosting the connection. Connecting as client means that you are being hosted by another device - and/or the device you are connecting to is the host.
I am trying to build an app that can connect via bluetooth and control a device. My first use case is my TV. so I want to make my app that can connect to my TV and control it as a remote. My initial thought is that the TV would act as the server. If I am connecting to another phone then I would imagine that my device would need to be the server. In most cases, if I want my app to act as a controller to send control signals to the device it connects to - is it correct to assume that my device is client or server?

Assuming that you mean Bluetooth Low Energy (BLE), then there are two separate types of roles that dictate how communication happens in Android:-
Central vs Peripheral - This has to do with the connection establishment and maintenance as follows:-
Peripheral device is the one responsible for advertising its presence as well as accepting incoming connections. Sensors usually fall into this category.
Central device is the one responsible for scanning and establishing the connection with the remote peripheral device. Phones usually fall into this category.
GATT client vs GATT server - This dictates how communication is handled when that connection is made:-
GATT server is the device that hosts all the data. Again, sensors usually fall into this category.
GATT client is the device that reads the data from the GATT server. Again, phones and computers usually take the GATT client role.
The two types of roles are separate (i.e. a Central can be a GATT server or a GATT client, and vice versa), but in the majority of the cases, the central is the GATT client.
And to finally answer your question, I would make the remote controller to be both the central and the GATT client. This way your TV would always be advertising its presence and hosting the date, while the remote scans/connects and reads/writes to that data.
You can find more information in the links below:-
The ultimate guide to Android BLE development
Bluetooth Low Energy: A primer
Android BLE examples

Client because when is server tv, you can connect from more clients (mobiles).
When is server mobile you can controll more tvs, but tv can connect only to defined mobiles.

Related

Can an Android app discover a local BLE GATT server?

If Android app A sets up a BLE GATT server, can Android app B (on the same device) discover and connect to that GATT server as a client?
No this shouldn't be possible because Bluetooth doesn't allow a device to connect to itself. I can't find in the spec where it specifically states this, but I have tried to do this using different Bluetooth stacks in the past and I wasn't able to.
Some information is provided here:-
Loopback in Android Bluetooth

Disconnecting and closing BLE connection stops classic Blutetooth PBAP profile

I have a setup with two Android devices: an android phone and a custom hardware running Android 10. The latter acts as a BLE Server, which is discoverable always with the same static MAC address. Also when that custom HW is paired with the phone it has access to phone's contacts and calls history. That HW can also play media (sound) streamed from the phone.
I use RxAndroidBle 1.11.0 library for BLE communication. As soon as I exchange some data via BLE Characteristic I unsubscribe from the RX observable so the library effectively calls: bluetoothGatt.disconnect() then blutetoohGatt.close()
(all those inside the DisconnectOperation class).
My problem is the fact that based on my observations, calling blutetoohGatt.disconnect() disconnects the classic BT profile (PBAP) as well.
Is it an expected behaviour?
I have investigated the code of generic Android P framework and it looks that calling bluetoothGatt.disconnect() -> bluetoothGatt.close() completely disconnects the device described by the given MAC Address:
BluteoothGatt#disconnect()
BlutetoothGatt#close()
BlutetoothGatt#unregisterApp()
I would risk a statement that I have quite unusual BLE use-case scenario where the phone (Central/Client) and the peripheral (custom Android HW/Server) are connected simultaneously via Classic BT profile and via BLE.
I suspect that disconnecting/closing device using its BT MAC address disconnect both profiles, hence the contacts sharing stops working.
Is it possible to disconnect BLE connection only, but not affect the classic BT (SPP/PBAP) connections between the two devices?
After further investigation described on that Github issue
I realised that my custom hardware is equipped with dual-mode BT adapter so it supports classic BT (BR/EDR) and the BLE one.
As soon as I pair an Android phone with the custom hardware via System Settings, classic BT profiles are bonded, but also my GATT Server advertises relevant services using the same MAC address which is used by the BR/EDR. Disconnecting BLE client connection disconnect BD/EDR as well.
What helps in my case is to not start pairing via System Settings, but let the GATT server advertise and let my BLE client app to connect (and trigger pairing) first. As a result I have a BLE connection with server available under "AA:AA:AA:AA:xx", while the classic BT profiles are connected to "BB:BB:BB:BB:yy" interface on the custom hardware.
Now, disconnecting BLE profile does not disconnect the classic one.
I am looking for a solution which would allow my GATT Server to be advertised with BLE only, but no luck so far.
Here are some interesting links I have found:
connectGatt creates connection over BT Classic instead of BLE
how to force BLE "just works" pairing in Android
BLE Dual-Mode

how to connect an embedded device to bluetooth chat application in android?

I have a bluetooth hardware device ( embedded one ) that is acting as a client and connecting with pairing permissions automatically to any device whose bluetooth is ON. But it is not connecting to the BT chat application installed on my android phone. The BT chat application works fine when it connects to my hardware device as a slave. But in case of my hardware device acting as a client and BT chat acting as a listening server, connection fails.
Does the AcceptThread code works only on application level and not on system level?
The hardware device connects my android phone at system level but not to bluetooth chat application.
Is there any solution?
Bluetooth chat app basically supports only classic bluetooth.
Please check the bluetooth profile of your embedded device. Does your embedded device supports classic bluetooth?
I suspect your chat application is using createRfcommSocketToServiceRecord().
Use the createInsecureRfcommSocketToServiceRecord instead. Insecure socket allows the RFCOMM to communicate with a non-authenticated paired device. Embedded devices like the RN42 or KC2114 have a difficult time performing authenticated pairing, because user interaction is required (numeric comparison, yes-no response). The "Just Works" automatic pairing will not produce an authenticated pairing. KC2114 supports both automatic authenticated pairing (with a small hack) and Just Works non-authenticated pairing.

Is there a way to isolate and control the Bluetooth pairing process programmatically in Android?

My applications connects my Android phone to a health device. The health device is capable of connecting using either Bluetooth SPP or HDP profile while my app can only support SPP.
The health device's documentation states that I have to send a special command to the it during the pairing process to make sure that Bluetooth communication uses SPP profile instead of HDP.
Note that I'm not concerned about connection after pairing at all. I need to:
Separate the pairing process from the connections after pairing - I don't mind if users have to authorise pairing through a popup
Be able to send some data to the health device during the pairing process (so that following connections will actually happen)
The Android documentation seems to imply that pairing is implicitly handled as an integrated part of the Bluetooth connections as you call connect() or accept(). However, this and this gives me some hope.
I'd like to support as many devices as possible but 4.0 and above are more important. The health device I'm using supports Bluetooth 2.1 so no worries about PIN.

How to find out which Bluetooth profile is used for communication

I need to use Bluetooth for communication with another application which sends data via bluetooth SPP profile. I use the Bluetooth Chat app from Android developer site. I am using real phone (HTC Desire) as there is no Bluetooth API in Android emulator. I use a BlueSoleil bluetooth dongle.
When the other application tries to connect to my phone via Bluetooth and send data via SPP, it is not possible to connect the phone to the application. So I tried Windows Hyperterminal to send data and connect the phone through the dongle. In this situation, I can receive the data and display on the phone.
I would like to know how to find out which bluetooth profile was used when communicating with Hyperterminal.
I have read that bluetooth stack has a buggy implementation in HTC Desire and the SPP profile doesn't work consistently always.
Appreciate any suggestion and time spent on this.
Cheers,
Madhu Nandan
In the case of your Hyperterminal communication - SPP profile that was most likely used.
SPP profile is a generic profile that just establishes the RFCOMM data channel and sets up a virual COM port for applications to open and connect to and send data.
SPP does not specify any data formats or application level communication protocol to be used by application.
So applications at both end should establish the required format/protocol for communication.
Applications sets it selfs up on a virtual COM (over SPP) and advertises itself (on SDP) via a unique UUID (And Service Names)
So I would suggest that you use the chat application as a starting point, and start with connection / reading data etc, then modify it and complete the application that talks to your application on the device.
(The chat example is meant to work with a remote chat of the same type and is not a generic usage for SPP profile application)
Hope this helps you.

Categories

Resources