11package com .termux .api .apis ;
22
3+ import android .annotation .SuppressLint ;
34import android .content .Context ;
45import android .content .Intent ;
56import android .content .IntentFilter ;
67import android .os .BatteryManager ;
8+ import android .os .Build ;
79import android .util .JsonWriter ;
810
911import com .termux .api .TermuxApiReceiver ;
@@ -15,17 +17,22 @@ public class BatteryStatusAPI {
1517
1618 private static final String LOG_TAG = "BatteryStatusAPI" ;
1719
20+ private static int sTargetSdkVersion ;
21+
1822 public static void onReceive (TermuxApiReceiver apiReceiver , final Context context , Intent intent ) {
1923 Logger .logDebug (LOG_TAG , "onReceive" );
2024
25+ sTargetSdkVersion = context .getApplicationContext ().getApplicationInfo ().targetSdkVersion ;
26+
2127 ResultReturner .returnData (apiReceiver , intent , new ResultJsonWriter () {
28+ @ SuppressLint ("DefaultLocale" )
2229 @ Override
2330 public void writeJson (JsonWriter out ) throws Exception {
31+ // - https://cs.android.com/android/platform/superproject/+/android-15.0.0_r1:frameworks/base/services/core/java/com/android/server/BatteryService.java;l=745
2432 Intent batteryStatus = context .registerReceiver (null , new IntentFilter (Intent .ACTION_BATTERY_CHANGED ));
2533
26- int level = batteryStatus .getIntExtra (BatteryManager .EXTRA_LEVEL , -1 );
27- int scale = batteryStatus .getIntExtra (BatteryManager .EXTRA_SCALE , -1 );
28- final int batteryPercentage = (level * 100 ) / scale ;
34+ int batteryLevel = batteryStatus .getIntExtra (BatteryManager .EXTRA_LEVEL , -1 );
35+ int batteryScale = batteryStatus .getIntExtra (BatteryManager .EXTRA_SCALE , -1 );
2936
3037 int health = batteryStatus .getIntExtra (BatteryManager .EXTRA_HEALTH , -1 );
3138 String batteryHealth ;
@@ -67,6 +74,9 @@ public void writeJson(JsonWriter out) throws Exception {
6774 case BatteryManager .BATTERY_PLUGGED_AC :
6875 batteryPlugged = "PLUGGED_AC" ;
6976 break ;
77+ case BatteryManager .BATTERY_PLUGGED_DOCK :
78+ batteryPlugged = "PLUGGED_DOCK" ;
79+ break ;
7080 case BatteryManager .BATTERY_PLUGGED_USB :
7181 batteryPlugged = "PLUGGED_USB" ;
7282 break ;
@@ -102,18 +112,75 @@ public void writeJson(JsonWriter out) throws Exception {
102112 batteryStatusString = "UNKNOWN" ;
103113 }
104114
115+ // - https://stackoverflow.com/questions/24500795/android-battery-voltage-unit-discrepancies
116+ int batteryVoltage = batteryStatus .getIntExtra (BatteryManager .EXTRA_VOLTAGE , -1 );
117+ // If in V, convert to mV.
118+ if (batteryVoltage < 100 ) {
119+ Logger .logVerbose (LOG_TAG , "Fixing voltage from " + batteryVoltage + " to " + (batteryVoltage * 1000 ));
120+ batteryVoltage = batteryVoltage * 1000 ;
121+ }
122+
105123 BatteryManager batteryManager = (BatteryManager ) context .getSystemService (Context .BATTERY_SERVICE );
106124
125+ // > Instantaneous battery current in microamperes, as an integer.
126+ // > Positive values indicate net current entering the battery from a charge source,
127+ // > negative values indicate net current discharging from the battery.
128+ // However, some devices may return negative values while charging, and positive
129+ // values while discharging. Inverting sign based on charging state is not a
130+ // possibility as charging current may be lower than current being used by device if
131+ // charger does not output enough current, and will result in false inversions.
132+ // - https://developer.android.com/reference/android/os/BatteryManager#BATTERY_PROPERTY_CURRENT_NOW
133+ // - https://issuetracker.google.com/issues/37131318
134+ int batteryCurrentNow = getIntProperty (batteryManager , BatteryManager .BATTERY_PROPERTY_CURRENT_NOW );
135+
136+ // - https://stackoverflow.com/questions/64532112/batterymanagers-battery-property-current-now-returning-0-or-incorrect-current-v
137+ if (Math .abs (batteryCurrentNow / 1000 ) < 1.0 ) {
138+ Logger .logVerbose (LOG_TAG , "Fixing current_now from " + batteryCurrentNow + " to " + (batteryCurrentNow * 1000 ));
139+ batteryCurrentNow = batteryCurrentNow * 1000 ;
140+ }
141+
107142 out .beginObject ();
143+ out .name ("present" ).value (batteryStatus .getBooleanExtra (BatteryManager .EXTRA_PRESENT , false ));
144+ out .name ("technology" ).value (batteryStatus .getStringExtra (BatteryManager .EXTRA_TECHNOLOGY ));
108145 out .name ("health" ).value (batteryHealth );
109- out .name ("percentage" ).value (batteryPercentage );
110146 out .name ("plugged" ).value (batteryPlugged );
111147 out .name ("status" ).value (batteryStatusString );
112- out .name ("temperature" ).value (batteryTemperature );
113- out .name ("current" ).value (batteryManager .getLongProperty (BatteryManager .BATTERY_PROPERTY_CURRENT_NOW ));
148+ out .name ("temperature" ).value (String .format ("%.1f" , batteryTemperature ));
149+ out .name ("voltage" ).value (batteryVoltage );
150+ out .name ("current" ).value (batteryCurrentNow );
151+ out .name ("current_average" ).value (getIntProperty (batteryManager , BatteryManager .BATTERY_PROPERTY_CURRENT_AVERAGE ));
152+ out .name ("percentage" ).value (getIntProperty (batteryManager , BatteryManager .BATTERY_PROPERTY_CAPACITY ));
153+ out .name ("level" ).value (batteryLevel );
154+ out .name ("scale" ).value (batteryScale );
155+ out .name ("charge_counter" ).value (getIntProperty (batteryManager , BatteryManager .BATTERY_PROPERTY_CHARGE_COUNTER ));
156+ out .name ("energy" ).value (getLongProperty (batteryManager , BatteryManager .BATTERY_PROPERTY_ENERGY_COUNTER ));
157+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .UPSIDE_DOWN_CAKE ) {
158+ int batteryCycle = batteryStatus .getIntExtra (BatteryManager .EXTRA_CYCLE_COUNT , -1 );
159+ out .name ("cycle" ).value (batteryCycle != -1 ? batteryCycle : null );
160+ }
114161 out .endObject ();
115162 }
116163 });
164+ }
165+
166+ /**
167+ * - https://developer.android.com/reference/android/os/BatteryManager.html#getIntProperty(int)
168+ */
169+ private static Integer getIntProperty (BatteryManager batteryManager , int id ) {
170+ if (batteryManager == null ) return null ;
171+ int value = batteryManager .getIntProperty (id );
172+ if (sTargetSdkVersion < Build .VERSION_CODES .P )
173+ return value != 0 ? value : null ;
174+ else
175+ return value != Integer .MIN_VALUE ? value : null ;
176+ }
117177
178+ /**
179+ * - https://developer.android.com/reference/android/os/BatteryManager.html#getLongProperty(int)
180+ */
181+ private static Long getLongProperty (BatteryManager batteryManager , int id ) {
182+ if (batteryManager == null ) return null ;
183+ long value = batteryManager .getLongProperty (id );
184+ return value != Long .MIN_VALUE ? value : null ;
118185 }
119186}
0 commit comments