I'm currently trying to make an Android app that will have some interaction with a BLE device. That device doesn't have the Ibeacon protocol.
What I want to do is auto connect to that device every time it is in range even (and almost 99% of the time) when the app is not in foreground. The only thing I know is that it is a BLE device, I have access to it name and address (00:1E:C0:29:BD:F8).
It is crucial tha the app connect to it every time it come in range. Even if the phone is lock it must connect no matter what (except if the phone is shut down XD). But as soon as the phone has booted and that bluetooth is activated, I must be sure that my app will be able to connect to tha device if it come in range.
I wanted to know what is the best way to do so.
The only way I can think of is to start a service as sticky, that will scan every 15 seconds (or something similar) for the device it already has registered to auto-connect.
The downfall of that method I guess is that it will surely drain the battery, I'm not sure about that but doing a scan for 3 to 4 second every 15 second must use up a lot of battery.
What do you guys think of that ?
Does anybody know a better solution I could use ?
Thank in advance for the help.
Related
We have a device that need to be started at night, the device is started thanks to a bluetooth command sent by a mobile application. It's possible to send this command while the app is in the background and keep monitoring the device (i.e. receiving data), for example, for 30 minutes?
If it's possible what would be the ways to implement this feature in iOS and Android?
Update: Think about a sleep tracking device; the problem shouldn't be to scan all night because the user must connect the device before go to bed (and eventually try to automatically reconnect to a known device, without the need to scan). I'm asking if it's possible to stay connected and send/receive data while, for example, updating an internal database all night.
Several thing to take into account about Android BLE system development, read this for more information: https://blog.classycode.com/undocumented-android-7-ble-behavior-changes-d1a9bd87d983
BLE Scanning has an abuse prevention since Android 7. What does this means?
Prevention for an app stopping and starting BLE scans more than 5
times in a window of 30 seconds.
Long-running scans are converted into opportunistic scans. (30 minutes).
About the background process depends on what type of service you want. You can start a foreground service with a notification or you can start a Job which runs always in the background with no notification.
If you can be more precise on how the system is going to work I can give a more detailed explanation.
What I want to know:
I'm wondering how the android system (like Android smart phone) auto-connects to devices which is paired before.
For example, I pair my bluetooth headset with my android smartphone in the procedure of "turn on scanning/advertising -> click pairing" on day 1. And when I turn on advertising on my headset, it connects automatically on day 2, 3, 4, and so on. The point is, I don't have to make my smartphone scan again to find my (paired) headset.
I can't understand how android system finds that the paired device is turned on. Does the android system scan periodically in background? Even if I don't click "scan" button?
Why I ask:
I want to make my app autoconnect to customized BLE device, after make pairing. I succeed to make pairing(bonding) with createBond() method, but after that, I couldn't find how to make autoconnect. I know I can turn on autoconnect function like this way, connectGatt(XXX, true, XXX), but this autoconnect function doesn't work when the BLE device is disconnected a few days.
So I want to make my app works like android system and Bluetooth headset. But I couldn't find how android bluetooth system works even I dig AOSP codes.
I found many questions (here and here) about problems like mine but there were no answers.
Thanks in advance.
Update:
I found that bt_btif gets activated (with LG smartphone and Nexus 5) when the paired headset is turned on (start advertising). But bt_btif doesn't get activated with my custom BLE device... What can I do?
Executing connectGatt(XXX, true, XXX) is the correct way to go. gatt.connect() also starts an auto connect. Once you execute that, your phone will scan for the device and once it appears it connects to it. The only thing that interrupt this call is either if Bluetooth is turned off on the phone or if your app process is being killed. To avoid your process from being killed, let your app have a foreground service.
One gotcha however, there is a bug in Android which will sometimes make auto connect do a direct connect instead (and cancel after 30 seconds or so). See https://code.google.com/p/android/issues/detail?id=69834. You need to use reflection to avoid this bug.
I think I found a solution.
First, the solution for my question: Android smartphone seems to detect state changes of nearby bluetooth devices from the hardware sides. When the paired bluetooth headset starts to advertise, a callback in HAL (I think) is called.
So I made my app to connectGatt with autoConnection=True to the device that I want, by using MAC address, when the activity is started (in onResume() of MainActivity).
The connection would fail if my BLE peripheral device is not advertising. But the device auto-connects when it starts advertising, because the autoConnection parameter was set to true.
I've done a similar app and i didn't have problem with that. As a last resort for your problem, i would suggest writing the BLE Device Address in a simple DB table and manually connect to it. I've made something like this here
. It is no best practice code, but i hope you can find ideas for you solution.
I would like to ask for your valuable opinion about the following:
I'm developing an Android app that needs to connect with the BLE device (whose name I know) automatically on starting the app. Furthermore, the app should be able to keep the phone connected to the BLE device (there will be no "connect" and "disconnect" buttons on the app screen). In other words, if established connection is lost for some reason, the app should be capable to detect this and to re-connect again. The user of the app don't need to be aware of this background process. For him/her, it is only important that the phone is connected with the BLE device.
Simply speaking, I know the name of the BLE device (it is called 'HMSoft'). How should I keep the app connected with this BLE module? Should I use some Thread that will do the job for me in parallel with my other activities within the app MainActivity? Or there is some better approach? Did you have similar experience in the past?
Thank you very much for your time and effort. I really appreciate it.
Sincerely,
Bojan.
You will want to wrap the BLE implementation up in a Service. Within that Service, you will have to implement the logic to connect to the BLE device and keep trying to connect to that BLE device if it becomes unavailable.
I'd like to use android's bluetooth for some kind of sensing devices. But I don't want to connect to these devices. As far as I know Devices won't react to scanning when their own bluetooth is disabled. But is there any way to get my app noticed when such a scan has been performed by a remote device, even when my app is running with bluetooth turned off?
I don't want to force toggling bluetooth on, but I need to get some kind of Action started in other devices running the same app. So I'm wondering if some there is any description/data field that can be sent with a bluetooth scan, so if scan is rejected the app has the opportunity to read that data just to know there was this specific call?
I need to leverage context-awareness within my system as to users, not knowing each other, still can interchange content (if they agree). But I need to find some ways of sensing while I also don't want to have all sensors activated all the time.
Hope you can give me a hint, or tell me that this is simply not possible, which would also help me not spending any more time on that.
Thanks.
I'm looking for a way to detect the disconnection of a Bluetooth device immediately after it has happened (2 second max), typically in a "device too far" scenario or Device battery is dead. Currently I can detect it with a BroadcastReceiver by getting a BluetoothDevice.ACTION_ACL_DISCONNECTED, but it takes about 16 to 20 seconds to fire.
Is there any way to get notified in 2 seconds Max.
I used BroadcatReceiver but it is not fast enough to get alert in 2 seconds Max, so is there any other kind of approach available to get notification quickly that bluetooth is disconnected.
I use this createRfcommSocketToServiceRecord(UUID); to connect a paired device and i am bound to use it using UUID.
I have visited a lot of links regarding this issue, but no one matches with my needs.that's why any help would be appreciated.
thanks.
I think the only way you can reliably sense loss of connection quickly (within two seconds) is via your own application protocol that you use over the Bluetooth connection. For example, your application protocol might implement a heartbeat that occurs every 500ms. If you don't see a heartbeat within two seconds then you could trigger your own event.
Bluetooth is a socket-based stream protocol that is designed to work over an unreliable medium (i.e. radio), and as such has to tolerate errors in (or loss of) packets. For this reason it will take significantly more than 2 seconds before your Bluetooth stack declares it has given up and disconnected the device, as you have found.
I have an application on Play which is designed to talk with an automotive ECU via Bluetooth and my strategy for sensing disconnection is exactly as I suggested in my first paragraph.
Update 20th June 14
I see in your bounty comment and also your comment below that you're asking for a code example, but it's kind of difficult for me to provide one without knowing anything about the application protocol that you're running over the socket connection. Or to put it another way, what exactly is it about my first paragraph (i.e. the heartbeat suggestion) that you do not understand or cannot create code for yourself? The concept of using a heartbeat really is quite simple. You would define a certain message type in your application protocol that represents a heartbeat message. One end of the connection sends this heartbeat message periodically, say every one second. The other end of the connection checks that this heartbeat message is received every second or so and drops the connection after a two-second time-out. It is impossible to be any more specific than that, because I can't see your existing code and I don't know what kind of messages you are currently exchanging over the socket.
After nothing work around!
I got two things to get my work done.
I need to check that is my Bluetooth socket is not in use(Sending Receiving) till 2 to 5 sec I disconnect that and when user wants to send data to the receiver device I connect that again.
Or I'll try to connect the socket after 2 to 5 sec so that if it is not ready to connect means it is already connected, else it will be connected and I refresh the previous socket references.
but first option is more valuable to work perfectly in my problem.
This is a problem with old bluetooth and more hardware than software.
If you want to notice that the connection is broken you need to do polling (a heartbeat), something like "are you alive? are you alive?"... This is bad for battery so... the users will finally uninstall your app.
I recommend you to change to BTLE (bluetooth low energy), devices like Nexus 5 has this.
With BTLE you have a proximity profile which can tell you the quality of the signal, so, you can guess the distance (near, far, out of range) and therefore you can also tell if the devices are disconnected.
Another nice point is that if the devices are out of range but one is again in range you could get noticed as well, so this is really nice for apps to open doors by proximity for example.
Check this:
https://developer.bluetooth.org/TechnologyOverview/Pages/PXP.aspx
In the other hand Apple has invented the concept of iBeacons, devices that are distance aware, and the good thing is that there is also an implementation of iBeacons for Android:
http://developer.radiusnetworks.com/ibeacon/android/