I have: 1) An embedded device with a Bluetooth connector that I use with BlueZ, and 2) I have an Android phone that I am writing an application on.
Goal: I want to make sure that when these two devices are near each other, they quickly detect each other and establish communication. Unfortunately, I'm running in to complications of what is feasible on Android and power efficient.
Initial Design: Originally, I've been thinking and implementing the following --
Embedded Device: Constantly in discoverable mode, creates a service with an RFCOMM server running to accept multiple connections.
Android Phone: Listen for Broadcast intents that would tell me when the embedded device (discoverable) is nearby, and then create an RFCOMM client socket to it.
The difficulty I am having with this design is that I do not get intents when I would expect them. Even if I turn the embedded device on and cycle the Android phone's Bluetooth adapter to off/on ... none of these Broadcast intents are received:
BluetoothDevice.ACTION_FOUND
BluetoothDevice.ACTION_ACL_CONNECTED
BluetoothDevice.ACTION_BOND_STATE_CHANGED
The only thing that seems to work is to periodically either have the phone try to connect to the Bluetooth device's RFCOMM socket, or to periodically trigger Bluetooth scans (both power inefficient). This will trigger ACTION_FOUND and ACTION_ACL_CONNECTED. If i shutdown the embedded device, I will receive ACTION_ACL_DISCONNECTED. The issue, again, is that none of these are received if I do not explicitly have the phone try to initiate a socket connection. This is bad for power efficiency on the phone.
Do I have this logic backwards? Should the embedded device keep track of Bluetooth MAC addresses that it has paired with and be the RFCOMM client, whereas the Android application creates a service and is the RFCOMM server just hanging around and waiting for a connection? This seems logically backwards, though... I wouldn't think the Android phone would create a service or be the server to make this happen.
If I go in to my car, it almost immediately manages to establish a connection with my phone. So, I know this is possible!
The concrete questions I have are two-fold: 1) Is there something I am doing wrong with my "initial design" to make it more effective, and 2) Is the 2nd logic I propose what things like cars use to establish quick communication and poll frequently? (since the battery power of the car is not a concern...)
Related
I am trying to make an app, that when it sees a specific bluetooth device to connect to it and send a command and before loose that connection to send another command.
The device is standard bluetooth serial device.
Is there a way to check when i am going to loose the connection?
No unfortunately Bluetooth doesn't work this way. You are usually notified that the remote device disconnected and you can even get the disconnection reason (e.g. BT_HCI_REMOTE_USER_TERMINATED_CONNECTION), but by then it is already too late and the link between your device and the remote device is already lost. Generally speaking, the way a disconnection works is that there are empty Bluetooth packets sent back and forth between the two devices (similar to an ACK) to indicate that the link is alive. If that packet does not arrive after a certain timeout, the BLE stack throws an event to the application notifying it that the connection has been lost (i.e. a disconnection event).
If you are using Bluetooth Low Energy, and if you are in control of both devices (your one and the remote one), then you could implement additional communication on the advertising channels. This is not as efficient as performing the communication through a connection, but you can advertise this additional command upon disconnection, and the remote device would scan for this new command upon disconnection as well.
I hope this helps.
I would like to minimize the need for user involvement in working with SPP medical devices. The user should only have to pair the device and then connections happen automatically when the device becomes connectable. HDP classic devices are like this and so are BTLE devices (the latter takes work on Android).
So the obvious solution is after pairing, create the RFCOMM Socket and invoke the connect() method (and perhaps all the workarounds to handle the various bugs).
However, this blocking method times out after 12 or so seconds according to the documentation so if I really want to continuously be ready for the device when it 'comes on-line', I need to do this in a while-loop until the connection succeeds.
So the question is if I do this, will this continuous 'pinging' for the device overload the system and drain the battery? Given that something like this happens for HDP implementations on Android, they must also do something like this but maybe they reduce the frequency of pinging so it isn't so resource demanding.
Does anyone have any experience with attempting to do continuous monitoring for SPP devices? Thanks!
I have used Bluetooth SPP connection for industrial devices and had a similar problem. It does not seem a good idea to have a service trying to connect all the time, as it will need to always run on the background and drain more battery.
My solution would be if possible to have the SPP medical device to ask for connection once powered to the paired device(your android), or when you try to connect to the medical device, automate the connection procedure which should take about 1-2 seconds (if you can filter the devices by their MAC address(preferably) or name in your app)
Based on the bluetooth chip in your medical device, you should have plenty of connectivity options from this end, but if not you can try to connect on demand.
i have 2 devices that are in same wifi network and are connected. Now, i want to listen whenever the device gets disconnected or reconnects. I dont want to listen to wifi connectivity with device but the connectivity between 2 devices in same wifi network.
How can we do that ?
Its certainly possible by using Android's peer to peer connection.
This is from the above link.
The WifiP2pManager.ActionListener implemented in this snippet only
notifies you when the initiation succeeds or fails. To listen for
changes in connection state, implement the
WifiP2pManager.ConnectionInfoListener interface. Its
onConnectionInfoAvailable() callback will notify you when the state of
the connection changes. In cases where multiple devices are going to
be connected to a single device (like a game with 3 or more players,
or a chat app), one device will be designated the "group owner".
We can communicate between 2 phones in the same using regular Socket's.
Server Side Link
Client Side Link
If you have a large amount of data to transfer, internet sockets have a greater data capacity and will be faster. The other advantage is that there is no such thing as "out of range". You can connect the two devices wherever internet is available.
So a UDP broadcast would seem like a good option. I.e where 2 devices with same app are running and a packet is broadcasted from one device on a particular socket, where as the other side the app listens on that socket.
I am no Bluetooth specialist and wondering what possibilities are available to find already paired Bluetooth devices automatically when they are range of each other.
Background:
In our case an Android application needs to connect to a dedicated accessory via Bluetooth (Rfcomm). Both devices are known to each other (they are paired). The Android application registers a broadcast receiver. During the startup of the application, the app initiates a discovery to find the dedicated accessory. If the accessory is in range everything works great.
Problem:
The user starts the application outside the range of the dedicated accessory. The Android application tries to discover the accessory without success. Then the user goes into the range of the Bluetooth accessory. The broadcast receiver won’t get notified about the accessory that is in range now.
Similar Thread / Possible Solutions
Similar questions were already asked on stackoverflow (e.g. autoconnect to bluetooth device when in range).
But continuously trying to discover Bluetooth devices in range isn't what I am looking for because this would cause too much battery drain of the Android device.
Another solution would be to try to connect to the paired device in the onResume method of the Activity. This would work but has the disadvantage that the application can’t run in the background. So the user had to bring the application at least once to the foreground to initiate the connection.
A third idea I thought about is to implement a server socket into the Android application too. When the android application is started and the discovery finished without success, the Android application could create server socket and to listen to incoming notifications of the accessory. This would help in some scenarios (e.g. the user starts his application, approaches the accessory, activates the accessory and the accessory notifies the application on startup that it is in range now). But this is still no 100% solution because both devices can start outside the range of each other. Also it would be mandatory to implement additional functionality (Bluetooth server socket in the Android device…).
So I am wondering if better solutions exist. I am looking for a solution where no additional ServerSockets are required and I always get the notification that the two already paired devices are in range of each other :-)
Thanks for any help!
After connecting the device for the first time, keep the mac address in a local list.
On disconnect, use connectGatt with autoconnect set to true to automatically re-connect when you are in range.
Not a full solution, but maybe it's sufficient for your app to poll the accesory's presence whenever the screen is turned on? In that case, this may be helpful: Start Activity on wake up/sleep in Android
I'm attempting to write an app that involves connecting two android devices via bluetooth.
It is my understanding that one device acts as a server, listening for incoming connections while the other acts as the client, and initializes the connection using the server's MAC address.
Consider the following:
I have my android phone in my pocket, I start working on my android tablet. I want to connect the tablet to the phone (via bluetooth) without taking the phone out of my pocket (I do not want to pull out the phone and manually start listening for incoming connections).
What would be a good way to achieve this? It seems like I would have to make the phone the server, constantly listening for connections 24/7. However, my gut says this will violently drain the battery.
Any suggestions?
You are right, you could make your phone (or your tablet) the server. But it ought not use that much battery; once you set up a server socket and start accepting connections the code simple blocks and waits for an incoming connection. In my experience I haven't found this to be too much of a battery drain (but I have no hard figures to back that up).
If there is a UI involved with the server you'll want to split out the server socket into a separate thread so as to not block UI events.
Typically phones behave this way - i.e wait for incoming connections from paired devices. Waiting / Scanning for incoming connections is less power hungry than trying to find or connect to devices in a poll mode. Many bluetooth chips have low power scan which implements power efficient scanning.