有个需求是当设备未插入电池时,要求关机充电动画不显示百分比,修改显示为充电图标。上一篇文章简单介绍了下关机充电动画及充电百分比,本篇继续记录下关机充电动画部分。
Android Q - 修改关机充电动画(竖屏改成横屏显示)
根据需求分析,我们需要先找到判断电池是否在位的方法,然后根据判断显示画面。在Android 应用中只需通过 BatteryManager.EXTRA_PRESENT 就可以判断,而对于 .c 文件了解不深,需要深入了解一下。
首先阅读一下 battery.h 文件
#ifndef BATTERY_H_
#define BATTERY_H_
#define BATTERY_STATUS_UNKNOWN 0x10f5
#define BATTERY_STATUS_CHARGING 0x10f6
#define BATTERY_STATUS_DISCHARGING 0x10f7
#define BATTERY_STATUS_NOT_CHARGING 0x10f8
#define BATTERY_STATUS_FULL 0x10f9
#define BATTERY_HEALTH_UNKNOWN 0x10fa
#define BATTERY_HEALTH_GOOD 0x10fb
#define BATTERY_HEALTH_OVERHEAT 0x10fc
#define BATTERY_HEALTH_DEAD 0x10fd
#define BATTERY_HEALTH_OVER_VOLTAGE 0x10fe
#define BATTERY_HEALTH_UNSPECIFIED_FAILURE 0x10ff
#define BATTERY_HEALTH_COLD 0x10f4
enum gFieldID{
// members
mAcOnline = 0,
mUsbOnline,
mBatteryStatus,
mBatteryHealth,
mBatteryPresent,
mBatteryLevel,
mBatteryVoltage,
mBatteryTemperature,
mBatteryTechnology,
mBatteryEnd,
};
extern int battery_status_init(void);
extern void * battery_status_update(void * cookie);
extern int battery_ac_online(void);
extern int battery_usb_online(void);
extern int battery_capacity(void);
extern int battery_status(void);
extern int battery_health(void);
#endif // BATTERY_H_
并没看到关于 persent 相关函数,于是阅读 battery.c 找一下初始化状态的函数
int battery_status_init(void) {
char path[PATH_MAX];
struct dirent* entry;
DIR* dir = opendir(POWER_SUPPLY_PATH);
if (dir == NULL) {
LOGE("Could not open %s\n", POWER_SUPPLY_PATH);
return -1;
}
while ((entry = readdir(dir))) {
const char* name = entry->d_name;
// ignore "." and ".."
if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
continue;
}
char buf[20];
// Look for "type" file in each subdirectory
snprintf(path, sizeof(path), "%s/%s/type", POWER_SUPPLY_PATH, name);
int length = readFromFile(path, buf, sizeof(buf));
if (length > 0) {
if (buf[length - 1] == '\n')
buf[length - 1] = 0;
if (strcmp(buf, "Mains") == 0) {
snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
gPaths.acOnlinePath = strdup(path);
} else if (strcmp(buf, "USB") == 0) {
snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
gPaths.usbOnlinePath = strdup(path);
} else if (strcmp(buf, "Battery") == 0) {
snprintf(path, sizeof(path), "%s/%s/status", POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
gPaths.batteryStatusPath = strdup(path);
snprintf(path, sizeof(path), "%s/%s/health", POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
if (access(path, R_OK) == 0)
gPaths.batteryHealthPath = strdup(path);
snprintf(path, sizeof(path), "%s/%s/present", POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
gPaths.batteryPresentPath = strdup(path);
snprintf(path, sizeof(path), "%s/%s/capacity", POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
gPaths.batteryCapacityPath = strdup(path);
...
}
只展示了一部分,但是我们发现了 present,也就是说源代码支持电池在位的判断,只是未写接口,不支持调用,那我们由此仿写一下就可以了。判断函数完成了,界面的展示部分在 ui.c 完成的。上一篇写到修改电量百分比是在 draw_text_picture(int level) 函数中修改的,简单检索一下就会发现是在 draw_progress_locked(int level) 函数中调用的,因此修改部分如下:
文件清单:
vendor/sprd/proprietories-source/charge/battery.c
vendor/sprd/proprietories-source/charge/battery.h
vendor/sprd/proprietories-source/charge/ui.c
diff --git a/battery.c b/battery.c
index c1efb3c..8f76511 100644
--- a/battery.c
+++ b/battery.c
@@ -347,6 +347,15 @@ int battery_usb_online(void) {
pthread_mutex_unlock(&gBatteryMutex);
return ret;
}
+int battery_is_present(void) {
+ int ret;
+
+ pthread_mutex_lock(&gBatteryMutex);
+ setBooleanField(gPaths.batteryPresentPath, mBatteryPresent);
+ ret = PowerSupplyStatus[mBatteryPresent];
+ pthread_mutex_unlock(&gBatteryMutex);
+ return ret;
+}
int battery_capacity(void) {
int ret;
diff --git a/battery.h b/battery.h
index 7751ef4..13c2338 100644
--- a/battery.h
+++ b/battery.h
@@ -36,6 +36,7 @@ extern int battery_status_init(void);
extern void * battery_status_update(void * cookie);
extern int battery_ac_online(void);
extern int battery_usb_online(void);
+extern int battery_is_present(void);
extern int battery_capacity(void);
extern int battery_status(void);
extern int battery_health(void);
diff --git a/ui.c b/ui.c
index 11162a3..8f96ded 100644
--- a/ui.c
+++ b/ui.c
@@ -389,10 +389,17 @@ static void draw_progress_locked(int level) {
draw_time_line();
#endif
#ifdef PICTURE_SHOW_PERCENT_SUPPORT
- draw_text_picture(level);
+ if (!battery_is_present())
+ LOGE("lichang, 当前无电池,不显示百分比");
+ else
+ draw_text_picture(level);
#else
draw_text_xy((dy + height), (gr_fb_width()/2 - 20), bat);
#endif
+ if (!battery_is_present()) {
+ LOGE("lichang, 当前无电池,显示充电图标");
+ gr_blit(gProgressBarError[0], 0, 0, width, height, dx, dy);
+ } else {
if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL) {
frame = level * (PROGRESSBAR_INDETERMINATE_STATES - 1) / 100;
gr_blit(gProgressBarIndeterminate[frame], 0, 0, width, height, dx, dy);
@@ -405,6 +412,7 @@ static void draw_progress_locked(int level) {
frame = level * (PROGRESSBAR_INDETERMINATE_STATES - 1) / 100;
}
}
+ }
}
static void draw_text_line(int row, const char* t) {
电池不在位显示的界面为一张 error 图片,可仿照 static gr_surface gProgressBarError[3]; 初始化后调用 。