I'm working on an Android application that needs to scan nearby Wi-Fi access points on a regular basis. Currently the scan takes place every 2-3 minutes, which requires registering a BroadcastReceiver to capture the scan results, calling WifiManager's startScan method and processing the results (something that also requires network calls in my case). This loop consumes a lot of energy, and I want to improve my power consumption by implementing a smart power policy for the app.
Aside from scanning only on "busy hours" (for example, stopping the loop at night), I'm thinking about using the accelerometer through the SensorManager to detect whether the device is stationary (placed on a table) or in motion (in the user's pocket while walking, for example). Then, by determining if the device is moving, I can adjust the scan frequency (reduce when it is stationary, and increase when the device is in motion).
I have a few questions on the matter:
1) Will tracking accelerometer data on a regular basis be more power efficient than running the scan loop every 3-5 minutes? How much power will tracking the accelerometer really cost?
2) How can I determine if the device is stationary or in motion? I've seen many question online talking about detecting shakes and tilts, but there's not a lot of information about natural motion detection. Also, how frequently should I sample the sensor?
I think the best way is to use ActivityRecognitionApi class included in the google play sevices which is optimized for such goals. This class gives a method : requestActivityUpdates which is optimized to return device state with minimum consumption of power.
The activities are detected by periodically waking up the device and
reading short bursts of sensor data. It only makes use of low power
sensors in order to keep the power usage to a minimum.
I second Fouwad Wahabi’s answer to your question.
I would recommend taking another approach to the track accelerometer and your user’s activities. I’d integrate a free SDK (available online) such as:
1. Tranql
2. Neura
3. Atooma
Some of these SDK’s send you the details of the user’s activities as soon as they occur and use less than 1% of your battery.
Related
From what I understand monitoring provides you information when a region has become visible in the vicinity of your scans (with callbacks like regionentered, regionexit etc) and then ranging gives your information about beacons in that region.
So behind the screen is same bluetooth scan sufficient to call both callbacks? Or we need to start separate scans for each?
In theory, one scan is enough for doing all these. The scan callback provides enough information to calculate beacon region/ranges. (You can use libraries or write your own algorithm for these.)
However practically the app need to restart separate scans, just to protect the Bluetooth stack on your device. There are quite some device specific issues if you run one Bluetooth scan for long time. Restarting scan periodically will improve the stability significantly on some devices.
My requirement is to detect if a person is driving. I am a bit confused with the Google ActivityRecognitionApi documentation.
Does "IN_VEHICLE" mean that the vehicle is in motion or can it be a stationary as well.
Does Google ActivityRecognitionApi "IN_VEHICLE" use GPS along with accelerometer?
If no, do we need to use GPS as well to detect if the vehicle is in motion?
Does "IN_VEHICLE" mean that the vehicle is in motion or can it be a stationary as well?
Based from DetectedActivity, IN_VEHICLE simply means that the device is in a vehicle, such as a car.
Does Google ActivityRecognitionApi "IN_VEHICLE" use GPS along with accelerometer? If no, do we need to use GPS as well to detect if the vehicle is in motion?
This statement from the ActivityRecognitionApi documentation gives a clear answer on how activities are being recognized using the API:
The activities are detected by periodically waking up the device and reading short bursts of sensor data. It only makes use of low power sensors in order to keep the power usage to a minimum. For example, it can detect if the user is currently on foot, in a car, on a bicycle or still.
You may want to also check this article which focuses on using the Google Play Services Activity Recognition API to determine if the user is running, walking, in a vehicle, biking, or remaining still.
Lastly, with regards to the use of GPS and accelerometer, I suggest that you please check Motion Sensors documentation wherein it provides several sensors that let you monitor the motion of a device.
android.net.wifi.WifiManager has the startScan() method to perform a passive scan of the WiFi channel and when the scanning is completed onReceive() method is called to access the WiFi channel readings.
However, as this webpage shows, which I have also confirmed with my own code implementation, the passive scanning of the WiFi channels take different times with different phones. Sometimes, some platforms are even around 10 times slower..
I would like to know what causes the phones to use so much time. Is it the driver? Is it some energy saving features? Or none of them and something very different is the reason?
The article gives you a hint:
Passive scans are slower to perform, because the device needs to
listen on every channel for some period of time, waiting for
broadcast beacons. Beacon frames are transmitted by APs periodically
to announce the presence of a wireless LAN. Beacon frames contain all
the information about its network. This approach consumes less energy,
since the radio doesn't use transceiver, but only the receiver. It
also takes more time to finish, since it has to listen on every
channel.
Some period of time is different for each device. If you listen for too short a time on a channel, you might miss a beacon frame. Too long and it might take a while to enumerate all the available APs when the user first scans a new location.
Furthermore, I didn't see actual details on how those results were generated. One might imagine a smart algorithm would use a longer listen time when first in a new location but switch to shorter ones after it's been there for a while.
I'm creating an Android Wear app that tries to detect some of the hand movements, to do it, I need to continuously monitor the accelerometer output. I'm wondering how it will affect the battery life.
For phones, I know that there are methods like "disable accelerometer while screen is turned off" to save battery, but what's the battery cost in case of watches? Since Android watch can count your steps and it turns on the screen when you face it towards your face, I believe the accelerometer is turned-on all the time anyway.
in this case, will my app drain the battery?
(Calculations after receiving the accelerometer values will be pretty simple.)
I think most android wear devices keeps the accelerometer on all the time to monitor steps, tilt-to-wake etc. However, I think most or all of this devices handles this in a low powered CPU (Sensor hub) to allow the main CPU to sleep most of the time when the screen isn't on.
If you want to monitor the accelerometer from an app, it would require the main CPU to be up and running at all times and cause a huge battery drain (20-40 mAh). I've tried this in an attempt to create a sleep tracker and drained about 70% battery over night.
You could consider batching which allows you to continuously monitor the accelerometer while allowing the main CPU to sleep most of the time. Basically you tell the sensor subsystem to gather data while the rest of the system sleeps and you just set an alarm to wakeup at a fixed interval (around 10 s for most android wear devices) to gather the latest batch of data.
I noticed that when looking at the best practices for Bluetooth Low Energy(BLE), Apple mentions that using the API comparable the Android GATT's onNotificationChanged() is more efficient than calling calling getValue() on a characteristic that updates regularly.
"Though reading the value of a characteristic using the readValueForCharacteristic: method can be effective for some use cases, it is not the most efficient way to retrieve a value that changes. For most characteristic values that change—for instance, your heart rate at any given time—you should retrieve them by subscribing to them."
Link for reference
I am working on a device where we have multiple sensors (similar to the Text Insturment's CC2541). What is going on behind the scenes (i.e. Bluetooth antenna power, sensor activity) that makes the notifications more efficient?
I am seeing if it is beneficial to pace the transmission through setting the update period on the device, by pinging the device (the queries will be to get the reading 1-2 times a second for each sensor).
The difference is that generally event-driven behaviours are more efficient than polling behaviours. This is particularly important on a battery-powered device, such as a phone or an embedded sensor. Making a connection and reading a value requires transmission from both devices - consuming battery power.
Using notifications allows the device to transmit only when it has new data.
Consider a couple of different scenarios -
First, a temperature sensor. In many environments (rooms, even outdoors) temperatures are relatively stable - changing by a few degrees over minutes. If you poll the sensor every second then 99.99% of the time you are going to get the same answer as last time. If the sensor notifies when the temperature changes you will only transmit for 0.01% of the time - a huge saving in power.
Second, a heart-rate sensor which reports a "table" of rates and durations for that rate. The data here can change much more frequently and less predictably - you don't know when the wearer is going to start or stop exercising - but outside of these "edges" the heart rate may be quite stable - such as when resting, watching TV etc. In this case you could poll, but you are going to waste power during the stable periods. With notification the sensor can periodically notify that a new collection of heart rate information is available and the notification period will vary depending on how variable the heart rate is. The device could also notify immediately if it detected a serious but rare event (such as a heart-attack).
You can, of course, include a maximum time before a notification is forced on your sensor, such as 30 seconds, to ensure that the app receives regular updates even when "nothing" is happening - this still represents an 83% reduction in transmissions compared to polling twice a second.