Port Android battery status to Android 4.4 and earlier

* java/org/gnu/emacs/EmacsService.java (EmacsService)
(queryBattery19): New function.
(queryBattery): Call it on old systems.  Also, return AC line
status and temperature.
* lisp/battery.el (battery-android): Implement more format
directives.
* src/android.c (android_query_battery): Handle new status
fields.
* src/android.h (struct android_battery_state): Add `plugged'
and `temperature'.
* src/androidfns.c (Fandroid_query_battery): Return new fields.
This commit is contained in:
Po Lu 2023-03-10 09:40:41 +08:00
parent 4392423cb6
commit 488a75f2e2
5 changed files with 94 additions and 14 deletions

View file

@ -40,6 +40,7 @@
import android.content.Context;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.PackageManager;
@ -738,6 +739,36 @@ invocation of app_process (through android-emacs) can
}
}
private long[]
queryBattery19 ()
{
IntentFilter filter;
Intent battery;
long capacity, chargeCounter, currentAvg, currentNow;
long status, remaining, plugged, temp;
filter = new IntentFilter (Intent.ACTION_BATTERY_CHANGED);
battery = registerReceiver (null, filter);
if (battery == null)
return null;
capacity = battery.getIntExtra (BatteryManager.EXTRA_LEVEL, 0);
chargeCounter
= (battery.getIntExtra (BatteryManager.EXTRA_SCALE, 0)
/ battery.getIntExtra (BatteryManager.EXTRA_LEVEL, 100) * 100);
currentAvg = 0;
currentNow = 0;
status = battery.getIntExtra (BatteryManager.EXTRA_STATUS, 0);
remaining = -1;
plugged = battery.getIntExtra (BatteryManager.EXTRA_PLUGGED, 0);
temp = battery.getIntExtra (BatteryManager.EXTRA_TEMPERATURE, 0);
return new long[] { capacity, chargeCounter, currentAvg,
currentNow, remaining, status, plugged,
temp, };
}
/* Return the status of the battery. See struct
android_battery_status for the order of the elements
returned.
@ -750,14 +781,16 @@ invocation of app_process (through android-emacs) can
Object tem;
BatteryManager manager;
long capacity, chargeCounter, currentAvg, currentNow;
long status, remaining;
long status, remaining, plugged, temp;
int prop;
IntentFilter filter;
Intent battery;
/* Android 4.4 or earlier require applications to listen to
changes to the battery instead of querying for its status. */
/* Android 4.4 or earlier require applications to use a different
API to query the battery status. */
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
return null;
return queryBattery19 ();
tem = getSystemService (Context.BATTERY_SERVICE);
manager = (BatteryManager) tem;
@ -776,7 +809,8 @@ invocation of app_process (through android-emacs) can
only return ``charging'' or ``discharging''. */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
status = manager.getIntProperty (BatteryManager.BATTERY_PROPERTY_STATUS);
status
= manager.getIntProperty (BatteryManager.BATTERY_PROPERTY_STATUS);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
status = (manager.isCharging ()
? BatteryManager.BATTERY_STATUS_CHARGING
@ -789,8 +823,27 @@ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
remaining = manager.computeChargeTimeRemaining ();
plugged = -1;
temp = -1;
/* Now obtain additional information from the battery manager. */
filter = new IntentFilter (Intent.ACTION_BATTERY_CHANGED);
battery = registerReceiver (null, filter);
if (battery != null)
{
plugged = battery.getIntExtra (BatteryManager.EXTRA_PLUGGED, 0);
temp = battery.getIntExtra (BatteryManager.EXTRA_TEMPERATURE, 0);
/* Make status more reliable. */
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
status = battery.getIntExtra (BatteryManager.EXTRA_STATUS, 0);
}
return new long[] { capacity, chargeCounter, currentAvg,
currentNow, remaining, status, };
currentNow, remaining, status, plugged,
temp, };
}
/* Display the specified STRING in a small dialog box on the main

View file

@ -1089,9 +1089,11 @@ The following %-sequences are provided:
The following %-sequences are provided:
%c Current capacity (mAh)
%r Current rate of charge or discharge (mA)
%L AC line status (verbose).
%B Battery status (verbose)
%b Battery status, empty means high, `-' means low,
`+' means charging and `?' means unknown.
%d Temperature (in degrees Celsius)
%p Battery load percentage.
%m Remaining time (to charge) in minutes.
%h Remaining time (to charge) in hours.
@ -1139,7 +1141,14 @@ The following %-sequences are provided:
(cons ?m (or minutes "N/A"))
(cons ?h (or hours "N/A"))
(cons ?t (or remaining "N/A"))
(cons ?L "N/A")))))
(cons ?L (cl-case (nth 6 status)
(0 "off-line")
(1 "on-line")
(2 "on-line (dock)")
(3 "on-line (USB)")
(4 "on-line (wireless)")
(t "unknown")))
(cons ?t (/ (or (nth 7 status) 0) 10.0))))))
;;; Private functions.

View file

@ -5754,7 +5754,7 @@ android_get_current_api_level (void)
}
/* Query the status of the battery, and place it in *STATUS.
Value is 1 if the system is too old, else 0. */
Value is 1 upon failure, else 0. */
int
android_query_battery (struct android_battery_state *status)
@ -5783,6 +5783,8 @@ android_query_battery (struct android_battery_state *status)
status->current_now = longs[3];
status->remaining = longs[4];
status->status = longs[5];
status->plugged = longs[6];
status->temperature = longs[7];
(*android_java_env)->ReleaseLongArrayElements (android_java_env,
array, longs,

View file

@ -160,6 +160,18 @@ struct android_battery_state
but is not charging either.
1, if the battery state is unknown. */
int status;
/* The power source of the battery. Value is:
0, if on battery power.
1, for line power.
8, for dock power.
2, for USB power.
4, for wireless power. */
int plugged;
/* The temperature of the battery in 10 * degrees centigrade. */
int temperature;
};
extern Lisp_Object android_browse_url (Lisp_Object);

View file

@ -2797,11 +2797,13 @@ frame_parm_handler android_frame_parm_handlers[] =
DEFUN ("android-query-battery", Fandroid_query_battery,
Sandroid_query_battery, 0, 0, 0,
doc: /* Perform a query for battery information.
This function will not work before Android 5.0.
Value is nil upon failure, or a list of the form:
(CAPACITY CHARGE-COUNTER CURRENT-AVERAGE CURRENT-NOW STATUS
REMAINING)
REMAINING PLUGGED TEMP)
where REMAINING, CURRENT-AVERAGE, and CURRENT-NOW are undefined prior
to Android 5.0.
See the documentation at
@ -2822,12 +2824,14 @@ for more details about these values. */)
if (android_query_battery (&state))
return Qnil;
return listn (6, make_int (state.capacity),
make_int (state.charge_counter),
return listn (8, make_int (state.capacity),
make_fixnum (state.charge_counter),
make_int (state.current_average),
make_int (state.current_now),
make_int (state.status),
make_int (state.remaining));
make_fixnum (state.status),
make_int (state.remaining),
make_fixnum (state.plugged),
make_fixnum (state.temperature));
}
#endif