50
votes

Background:

Ideally I would like my Android device to be scanning for Bluetooth Low Energy devices all the time an the ability to start an application whenever a new device with specific properties appears.

So the broadcast packet in BLE will for instance enumerate a set of services provided by the broadcasting device. An app would then be able to register an interest for certain services and automatically be started when a device with this services comes into range.

From what I understand this is not how the Android BLE API works? So how can I get something similar?

Simplest possible example:

I have a BLE sensor that logs ambient temperature over time. Whenever my Android phone is close enough I want to connect and download all the data, sending it to some cloud storage solution. This app would not need any GUI (at least not after configuration is done). But how should it run in the background without draining the battery, but still give me a fairly good chance of connecting the device quickly once it is in range?

Question:

Do I need to set a timer and wake the app every once in a while and then manually start scanning? What kind of intervals should I then choose. How long can I leave the scanner running without adversely affecting the battery?

Possible solution:

This is what I've come up with so far.

  • A configuration activity to set the intervals and devices to scan for
  • The configuration activity will set up an WakefulBroadcastReceiver similar to the Scheduler example
  • When the receiver get's the onReceive event I start a BLE scan service (that I've written) as a wakeful service.
  • The scan service starts scanning (with a registered callback).
  • The service might get adv reports that it can act upon
  • After a timeout the service will stop the scanner and end the wakeful service.

This works, but I'm not sure it's the best way. I also don't know how small intervals I can have and still avoid destroying the battery life. What I would want is to start scanning every two minutes, scanning for 10-20 seconds. But I'm afraid that would be rather frequently to wake up the device?

1
I too have the same question. If someone can explain them, it would be awesome.user2847518
Scanning in the background is easy enough. Doing so without draining the battery is quite different. As you have probably seen in the Bluetooth LE sample code, scanning is an active process.David S.
@DShaw: Why does it have to be an active process? I start scanning and get the advertisement reports as callbacks. In between the device could sleep. I don't know how this works on Android, but on a low power embedded device the CPU would sleep while the radio is running.Vegar Westerlund
Running the radio to scan for devices is an active process and takes battery.Nathan Walters
@NathanWalters: The BLE radio is almost certainly a connectivity device, meaning it can run the scanner while the main CPU is sleeping. It's called low energy for a reason. The radio should be able to run a scanner at less than 200uA on average. That is negligible compared to the main CPU. The main CPU should wake up, start the scanner and go back to sleep in less than 1ms (maybe a few hundred us) and should then sleep while the radio is scanning only waking up to handle advertisement reports (which again should take a couple of hundred us pr event).Vegar Westerlund

1 Answers

23
votes

This functionality has all been moved to the open source Android Beacon Library which will:

  • wake up/launch your app when iBeacons matching a desired pattern are detected

  • perform beacon scanning in the background even if the user has not launched your app yet

  • reduce the scan rate automatically in the background to 30 seconds every five minutes to save battery. (Timing configurable.)

Code examples are show here

If your BLE device is not a beacon you could still use this library to accomplish this by having your sensor also transmit as a beacon then after it is detected connect to the main service.