My service records the location of the user and sends it to Firebase every X minutes. I have tried changing X from 1 minute to 5 minutes, however the change in battery drain was less than 1 percent. In both cases it works out at about 5% used by the app every 3 hours.
I am trying to understand how increasing the GPS interval by 500% had little or no impact on the battery life. Not only is the GPS firing 1/5 of the time, but there is also 1/5 of the data being sent/received to Firebase.
When the watching location is turned off, battery drain is 0.
Any ideas as to what is causing the drain? Also, what kind of battery drain should I be looking at for getting a GPS location every 5 mins and sending about 50 bytes of data with it?
An immediate concern is how you connect to Firebase. Keep in mind that Firebase will keep an open connection to the server from the moment you call new Firebase(...). If you only want to periodically send/listen for data, you'll needlessly be draining the battery.
You can programmatically manage the connection state with goOffline()/goOnline().
If you're only sending updates, you can use the Firebase REST API to write the updates. This won't keep an open connection, or at least leaves it up to Android to determine when to close the connection.
Turned out the major cause was the mobile data. As soon as I made it require wifi to use firebase the battery drain dropped from 20% a day to 2%.
Related
I have an app which updates the location to a web service every 10 seconds. However, on devices with API level 23 or greater, when doze mode kicks in after 15 minutes to inactivity, the network connectivity is lost, and the app becomes unable to send further location updates to my web service.
Other than whitelisting the app by asking for user permission to ignore battery optimizations, which only allows a location update once every 15 minutes, what are my other options to keep getting GPS location updates and be able to send them to my web service?
Though it is highly immoral to overcome doze mode, if the app can explain the issue with the battery to the user then it is better to whitelist the app.
The other option is to keep the screen on to avoid doze mode from getting triggered.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
This piece of code will keep the screen on. Make sure to create a black or empty layout like what battery saver in pokemon go does.
The Official Doze documentation allows whitelisting for your use case. Check it here.
You're running way too often to begin with. There's no phone that even updates location that fast- normal would be once every 30 to 60 seconds. So 2/3 to 5/6 of your updates are pointless. Ignoring that- if you're in a car going 60 mph you aren't going to change by more than 14 feet in 10 seconds. There's absolutely nothing you're doing on the server that needs to be accurate to 14 feet- the typical GPS in a phone is only accurate to 10 meters (over 30 feet). That's one of the reasons why GPS doesn't update more frequently.
But no, there isn't. They implemented Doze for a reason. It saves battery. They set it up so you can't get around it without asking the user if they want to burn that battery. I definitely understand why 15 minutes is too slow, but then you ask the user and let them decide if your app is worth it.
In my Android application I need to send a message to the server (basically a ping) once a minute when a certain feature is activated. The feature may be activated for 2-3 hours, so it's important that the ping is sent continuously and in a timely fashion.
To achieve this I am currently using AsyncTasks (for sending the request), launched once a minute via a foreground Service, which is scheduled with alarmManagers' setExactAndAllowWhileIdle. The foreground service does have a partial wakelock too!
Unfortunately it looks like Marshmallow's doze mode ends up swallowing the alarms at some random point. This happens EVERY TIME and at arbitrary points. Sometimes the app sends pings for 2 hours without problems, sometimes only for 30 minutes, before they don't go off anymore (and then restarting 10-15 minutes later).
What can I do to get the ping sent continuously? It is incredibly important for the app. The only other alternative I can see is that I use the GCM to send high-priority messages every 5 minutes or so to keep it alive, but I that would be a terrible hack.
Ask the user to add your app to the battery optimization whitelist.
Or, ask the user to only use this feature when connected to a charger or external battery pack.
Or, ask the user to jiggle their device every few minutes for a few moments, to try to convince Android that it is not sitting idle on a nightstand.
Or, build your own custom ROM, where you take steps to modify Android to allow your app to consume arbitrary amounts of power, then have users install your custom ROM.
Note that AFAIK your GCM solution would need to be every minute, not every five minutes, if you want to send "pings" every minute. The GCM solution does not prevent the device from going into Doze mode; it merely allows you to send messages to the app and have a brief window of connectivity. It is possible that the window is 5+ minutes, but I wouldn't count on it.
Note that you are saying, in effect, that the CPU will need to be on continuously for your 2-3 hour window, due to your partial WakeLock. You are also saying that some radio (WiFi or cellular) will be in a high-power mode for much of that time as well, since they go through a series of power states with relatively slow transition times, and an every-minute set of packets will push the radio back into the high-power state. What you are doing is exceptionally bad for battery life.
If your users agree that what you are doing is "incredibly important" to them, they will not mind adding you to the whitelist, or only using this feature while on a charger.
In my app I am going to use the GPS for getting direction when I am trying to use GPS system. on that time my mobile % of charger will reduce immediately, if there is any idea for overcome from in this issue.
You have to tell what you have done to make the battery consumption so high. (Not even clear if battery becomes 77% after 1 minute or 15 minutes or 1 hr).
How are you accessing GPS? Are you running a handler/thread to periodically poll the GPS. If yes, this is wrong approach. You can ask Android to inform you on location changes.
GPS services are usually memory hungry. Do you need GPS services or just looking for location updates? Android comes with a good startup doco for location based services . http://developer.android.com/guide/topics/location/obtaining-user-location.html Try following the steps in this doco to find best user location.
Make sure to stop listening for updates at the appropriate time. Users will not be happy that one app tries to drain the battery even when it is not running.
Try making the app as a background task.. i.e a Service or BroadcastReceiver
I have application which for every 10 seconds do some request to server (http client). I read a lot about application life cycle. My application has service with foreground flag and it's work well (application work all time) when android is "active". I don't have phone with real android, so I am testing on emulator, but my friend testing it on smartphone and he notice that when he leave his phone, request are post for 10, 30 minutes, even hour. If he turn on screen, then request time is back to 10 seconds (he have access to server so he see logs). Is this known behavior? Because he installed gmail notifier from google, and this same problem (big delay). Any solution for this? My service have timer task (so request is sent in async task)
Regards
First of all, if you're polling every 10 seconds, that's gonna drain a lot of battery and network bandwidth.
I recommend using a lower frequency or server push.
For the polling issue, how do you implemented the polling ?
Do you use timers ? if so, what options do you pass in ? Or do you use a thread that sleeps for 10 seconds ?
Depending on the version, Android may turn off all processes, or delay network requests to run every 30 minutes to preserver battery power and bandwidth. (Starting up the network components drain a lot of battery than keeping them running. So If your app turns ON network, do a poll, then simply turn it off, Android may schedule it to align with all other requests on the system.)
Can you provide us more info about how you do the polling ?
UPDATE
You might have to schedule a 'WakeLock' so android knows when to wake up for your service. I think, by default, android doesn't wake up for timer requests that are scheduled very frequently and it schedules them as I explained. WakeLocks on the other hand can force android to wake up.
See this question and WakeLock Documentation
Make sure you pass the correct parameters, so you don't turn the screen ON. (Would be really annoying.)
UPDATE
I still recommend using server push for this, which will save battery and bandwidth while keeping the updates real time.
I am developing an application which has two GPS services. One of which is location tracking which send location updates at every 2 min to server and another service is cyberseatbelt which checks for speed of device when location updates.
With these two services, battery consumption is 77% displayed in my mobile. Without these two services, no battery consumption is displaying.
Is there any solution to save battery power on device while keeping the desired functionality?
You have to tell what you have done to make the battery consumption so high. (Not even clear if battery becomes 77% after 1 minute or 15 minutes or 1 hr).
How are you accessing GPS? Are you running a handler/thread to periodically poll the GPS. If yes, this is wrong approach. You can ask Android to inform you on location changes.
GPS services are usually memory hungry. Do you need GPS services or just looking for location updates? Android comes with a good startup doco for location based services . http://developer.android.com/guide/topics/location/obtaining-user-location.html
Try following the steps in this doco to find best user location.
Make sure to stop listening for updates at the appropriate time. Users will not be happy that one app tries to drain the battery even when it is not running.
Try making the app as a background task.. i.e a Service or BroadcastReceiver