I want to get battery usage data from my OnePlus 5 over a longer period (months), to keep track of how much I use my phone.
I've been playing around with adb and the batterystats dump, like so:
adb shell dumpsys batterystats > batterystats.txt
,but this data only seems to cover the data since the last charge.
Is battery usage data even stored for a longer period on your phone? Or is it reset every time you charge it? If it is stored somewhere, how would I access it?
$ adb version
Android Debug Bridge version 1.0.39
Revision 3db08f2c6889-android
From the android documentation dumpsys service. As indicated I executed the following command adb shell dumpsys batterystats -h to get the available arguments
From my experimentations, battery logs records do not last more than few days (in my case 10 days on my motorola Moto x 2nd gen). You may have to plug and log the phone more often than each month
As printed by the -h argument you can use enable no-auto-reset by doing adb shell dumpsys batterystats enable no-auto-reset
no-auto-reset: don't automatically reset stats when unplugged
but you have to do it after each boot as indicated by the command
Option state is not saved across boots.
Related
I have an application that uses a ForegroundService to send location updates to a server. Basically a tracker.
This ForegroundService has a Handler that periodically (using postDelayed) executes a block of code to send the location.
This works perfectly fine, when the app is in the foreground and even in the background, but I started to notice a delay when the phone is locked, with the screen off for about 15minutes. I mean, 15 minutes of no user activity and no charger plugged.
This is happening on a Android Q (v10) device. I'm assuming this would also happen on any device running Oreo onwards.
Let's make it clear... My app send the location every 30sec, but when entering what I suppose is the DozeMode or AppStandByMode, it continues sending the location, but every 2 minutes (more or less). If I turn the screen on, or plug-in the charger it inmediately come back to the 30sec pace. That's what makes me thing about the DozeMode or AppStandByMode. Moreover, if I leave the phone untouched, but with the charger plugged in, then this never happens.
As said, I'm pretty sure the DozeMode or AppStandByMode is kicking in, and I know I can whitelist my app to prevent that. But before going further I would like to reproduce this without the need to wait those 15minutes every time I want to test the behavior of my app.
So I "googled" how I can force this and here's what I've found:
For DozeMode (see source)
adb shell dumpsys battery unplug
adb shell dumpsys deviceidle step deep
And continue to execute the last command until reaching IDLE state.
For AppStandByeMode (see source)
adb shell dumpsys battery unplug
adb shell am set-inactive packageName true
And query the state with this other command:
adb shell am get-inactive packageName
which I confirm it returns Idle=true
I also even do as this other blog suggest, issuing:
adb shell dumpsys deviceidle force-idle
I though I was not getting in this mode, but now it seems I am and I can not get out of it... See the update
UPDATE
At first I thought I was not entering the DozeMode... Now I can confirm I'm in, but it always triggers inmediately. (no more waiting those 15min)
Whenever I lock the phone and screen goes off, it automatically enters the doze mode and begin spacing the location updates. I plug the charger and then again sends them at 30sec.
I've try:
adb shell dumpsys deviceidle unforce
adb shell dumpsys deviceidle disable
adb shell dumpsys battery reset
and still the same.
Also:
power-down and power back up the phone
uninstall the app
change battery optimization to NOT OPTIMZE inside the app settings
Did I miss a step?
Except for Doze mode, Android 9 extended the concept of AppStandby with App Standby Buckets.
Along with network restrictions, an app that is in a low priority bucket will be affected in the frequency of running Jobs, triggering Alarms, and receiving FCM messages.
You can get your app's current bucket using this command:
adb shell am get-standby-bucket your.package.name
You can set the bucket and see how your app behaves using this command:
adb shell am set-standby-bucket your.package.name <never/rare>
I wrote an article that summarizes all changes regarding background process limitations over the years: https://rotemmatityahu.medium.com/workmanager-does-it-always-manage-to-work-fd8518655052
I need to calculate the power consumption of an Android smartphone using adb.
I know that there is Google Battery Historian, and I also know the command:
adb shell dumpsys batterystats
But I need something different: I want to launch an app (youtube for example) using adb for 10 minutes and, using adb (wireless) I want to collect the power consumption in milliamperes every second.
I know that there is a way to get the mA, but I cannot understand how.
I need to test whether an app behaves correctly after restoring from Doze / App standby. The thing is that when I use commands from the Android Developers site, nothing happens with either the app nor with the device itself. The command prompt seems to respond correctly though.
Commands for Doze:
adb shell dumpsys deviceidle unforce
adb shell dumpsys battery reset
Commands for App Standby:
adb shell dumpsys battery unplug
adb shell am set-inactive <packageName> true
Wake up from App Standby:
adb shell am set-inactive <packageName> false
adb shell am get-inactive <packageName>
https://developer.android.com/training/monitoring-device-state/doze-standby.html#testing_doze_and_app_standby
Do you think that if nothing bad happens to the app, it means that it is behaving correctly? Or have I made some mistakes during the tests? I'm asking because from what I've read on the internet, the Doze should trigger with at least locked screen, so it all looks suspicious to me. I don't have any other ideas how to confirm whether these commands actually work.
With the Doze test, make sure you force the system into idle mode by running the following command first:
adb shell dumpsys deviceidle force-idle
But otherwise the commands you are running look correct.
You primarily want to test that the app returns to a good state after being in Doze or App Standby mode, and that any restrictions in place during that mode are lifted. The restrictions Doze and App Standby may impose on apps include limited or no network access, suspended background tasks, suspended Notifications, ignored wake requests, and alarms.
If your app can send notifications or trigger alarms, you can test that those are blocked during this mode.
According to the Android docs:
Observe the behavior of your app when it is woken. Make sure it
recovers gracefully from standby mode. In particular, you should check
if your app's Notifications and background jobs continue to function
as expected.
I've looked all over the internet to find specifics about App Standby mode in Android Marshmallow, but I've not found any specific data for when it happens, other than some listed conditions that might cause it to happen. I also see a nebulous "If the device is idle for long periods of time, the system allows idle apps network access around once a day" without any specifics about how long this window would be.
Doze mode seems pretty well researched (This gist was particularly helpful and consistent with my findings), but I haven't been able to see App Standby in action. I created a test app that sends data to a server every 5 minutes via an Alarm and ran it for a week, and it continued to hit the server every 5 minutes unless the phone went into Doze mode and only hit the server in maintenance periods, then go back to every 5 minutes when the phone was awoken, so it did not appear that Android ever put it in "App Standby" state even though I didn't directly interact with the app.
Is there any specific data on how App Standby works?
You can force the device to enter this mode using the code below:
adb shell dumpsys deviceidle enable
adb shell dumpsys battery unplug
adb shell dumpsys deviceidle step
adb shell dumpsys deviceidle force-idle
I slightly modified this app :https://github.com/commonsguy/cw-omnibus/tree/master/JobScheduler
It set alarms using setExactAndAllowWhileIdle and schedules an alarm to go off every 1 minute and log it.
According to Doze documentation, if this app is running while the phone is in Doze mode, only one alarm should be going off per 15 minutes. I'm not seeing that behavior .
On a a nexus 5 running Android M. After starting the app and the whole alarm scheduling process, I put the phone into Doze using the provided abd commands...
adb shell dumpsys battery unplug
adb shell dumpsys deviceidle step
adb shell dumpsys deviceidle -h
...From the log, I have seen around 30 minutes of alarms going off once per minute, then finally they are 15 minutes apart for about an hour. Then back to once per minute, and then back to 15 minutes apart. The phone was completely undisturbed during the test.
Does anyone know why this is? I was under the impression that the phone would immediately be in Doze mode after those adb commands , and that the alarms would be going off 15 minutes apart from the start.
Thanks for your help.
For one thing, the relevant adb command docs are incomplete, as you noted in the link to ISSUE 2930.
The following command merely prints usage info:
adb shell dumpsys deviceidle -h
The following command will display the current state including the prerequisites (enabled, not moving, not charging, screen off) for getting into IDLE:
adb shell dumpsys deviceidle
Settings:
...
Whitelist (except idle) system apps:
...
Whitelist (except idle) all app ids:
...
mEnabled=true
mForceIdle=false
mSigMotionSensor=null
mCurDisplay=...
mScreenOn=false
mCharging=false
mSigMotionActive=false
mState=INACTIVE
That shows whether you need to do more setup. E.g. it seems to take 2 or 3 taps on the emulator's power button to get mScreenOn=false.
The following command steps towards IDLE mode, but ISSUE 2930 explains that you need to step multiple times to get to INACTIVE, IDLE_PENDING, SENSING, then IDLE:
adb shell dumpsys deviceidle step
The following command will force it into idle:
adb shell dumpsys deviceidle force-idle
BTW the developer docs on Doze and App Standby were improved recently.
The rate limit for setExactAndAllowWhileIdle is different when the device is in idle mode. I'm guessing it's taking you 30 minutes for your phone to enter idle mode via Doze, at which point you'll be limited to calling setExactAndAllowWhileIdle once every 15 minutes.
In Doze mode, your phone will wake up periodically for an Idle Maintenance period of up to 10 minutes. During those 10 minutes it will wake up from idle mode and your rate limit will be adjusted to once every minute. After the maintenance window ends, you're seeing it go back to once every 15 minutes.
The Idle Maintenance windows are described in the docs: http://developer.android.com/training/monitoring-device-state/doze-standby.html#understand_doze