BatteryService作为电池及充电相关的服务,它的实现非常简单:
o 监听UEvent,读取sysfs里中的状态。
实现了一个UEvent的观察者。uevent是Linux内核用来向用户空间主动上报事件的机制,对于JAVA程序来说,只实现UEventObserver的虚函数onUEvent,然后注册即可。
private UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
update();
}
};
这里只关注power_supply的事件:
mUEventObserver.startObserving("SUBSYSTEM=power_supply");
当有power_supply相关的事件上报时,就会调用update函数。
update先调用native_update从sysfs中读取相关状态(com_android_server_BatteryService.cpp),
"native_update"=>android_server_BatteryService_update:
Linux驱动提供了下列文件,供应用程序获取电源相关状态:
#define AC_ONLINE_PATH "/sys/class/power_supply/ac/online"
#define USB_ONLINE_PATH "/sys/class/power_supply/usb/online"
#define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status"
#define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health"
#define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present"
#define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity"
#define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol"
#define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp"
#define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology"
在<DA9034驱动程序阅读笔记(6)>一文中,我已经提到drivers/power /micco_power.c里注册了充电器(ac)、 usb和电池(battery)三个power_supply。各个power_supply提供的属性和上述文件是对应的,从这些文件中可以读到充电器 (ac)、usb和电池(battery)三个power_supply的相应状态。
update然后根据读到的状态更新BatteryService的成员变量,并广播一个 Intent来通知其它关注电源状态的组件。
private final void sendIntent() {
// Pack up the values and broadcast them to everyone
Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
try {
mBatteryStats.setOnBattery(mPlugType == BATTERY_PLUGGED_NONE, mBatteryLevel);
} catch (RemoteException e) {
// Should never happen.
}
int icon = getIcon(mBatteryLevel);
intent.putExtra("status", mBatteryStatus);
intent.putExtra("health", mBatteryHealth);
intent.putExtra("present", mBatteryPresent);
intent.putExtra("level", mBatteryLevel);
intent.putExtra("scale", BATTERY_SCALE);
intent.putExtra("icon-small", icon);
intent.putExtra("plugged", mPlugType);
intent.putExtra("voltage", mBatteryVoltage);
intent.putExtra("temperature", mBatteryTemperature);
intent.putExtra("technology", mBatteryTechnology);
ActivityManagerNative.broadcastStickyIntent(intent, null);
}
关注ACTION_BATTERY_CHANGED的地方有好几个:
o KeyguardUpdateMonitor 这里主要是用来更新锁屏界面下的电池状态。还有低电警告和关机也是在这里做的。
private void handleBatteryUpdate(int pluggedInStatus, int batteryLevel) {
if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
final boolean pluggedIn = isPluggedIn(pluggedInStatus);
if (isBatteryUpdateInteresting(pluggedIn, batteryLevel)) {
mBatteryLevel = batteryLevel;
mDevicePluggedIn = pluggedIn;
for (int i = 0; i < mInfoCallbacks.size(); i++) {
mInfoCallbacks.get(i).onRefreshBatteryInfo(
shouldShowBatteryInfo(), pluggedIn, batteryLevel);
}
}
// shut down gracefully if our battery is critically low and we are not powered
if (batteryLevel == 0 &&
pluggedInStatus != BATTERY_STATUS_CHARGING &&
pluggedInStatus != BATTERY_STATUS_UNKNOWN) {
ShutdownThread.shutdownAfterDisablingRadio(mContext, false);
}
}
o NotificationManagerService 用来更新充电状态(LED)
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
boolean batteryCharging = (intent.getIntExtra("plugged", 0) != 0);
int level = intent.getIntExtra("level", -1);
boolean batteryLow = (level >= 0 && level <= Power.LOW_BATTERY_THRESHOLD);
int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
boolean batteryFull = (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90);
if (batteryCharging != mBatteryCharging ||
batteryLow != mBatteryLow ||
batteryFull != mBatteryFull) {
mBatteryCharging = batteryCharging;
mBatteryLow = batteryLow;
mBatteryFull = batteryFull;
updateLights();
}
}
o PowerManagerService 这里主要是做两件事件,先是检查是否在充电时不允许睡眠,并采用相应的行动,其次是触发一个用户行为(会影响下一次睡眠的时间)。
private final class BatteryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLocks) {
boolean wasPowered = mIsPowered;
mIsPowered = mBatteryService.isPowered();
if (mIsPowered != wasPowered) {
// update mStayOnWhilePluggedIn wake lock
updateWakeLockLocked();
// treat plugging and unplugging the devices as a user activity.
// users find it disconcerting when they unplug the device
// and it shuts off right away.
// temporarily set mUserActivityAllowed to true so this will work
// even when the keyguard is on.
synchronized (mLocks) {
boolean savedActivityAllowed = mUserActivityAllowed;
mUserActivityAllowed = true;
userActivity(SystemClock.uptimeMillis(), false);
mUserActivityAllowed = savedActivityAllowed;
}
}
}
}
}
o LocationManagerService 这里似乎没有什么用处,我没找到mCollector赋值的地方。
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
log("PowerStateBroadcastReceiver: Battery changed");
synchronized (mLocationListeners) {
int scale = intent.getIntExtra(BATTERY_EXTRA_SCALE, 100);
int level = intent.getIntExtra(BATTERY_EXTRA_LEVEL, 0);
boolean plugged = intent.getIntExtra(BATTERY_EXTRA_PLUGGED, 0) != 0;
// Notify collector battery state
if (mCollector != null) {
mCollector.updateBatteryState(scale, level, plugged);
}
}
}
o WifiService 根据电源状态来决定是否需要定时唤醒(没搞得太明白,看Wifi服务时再研究)。
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
/*
* Set a timer to put Wi-Fi to sleep, but only if the screen is off
* AND we are transitioning from a state in which the device was supposed
* to stay awake to a state in which it is not supposed to stay awake.
* If "stay awake" state is not changing, we do nothing, to avoid resetting
* the already-set timer.
*/
int pluggedType = intent.getIntExtra("plugged", 0);
if (mScreenOff && shouldWifiStayAwake(stayAwakeConditions, mPluggedType) &&
!shouldWifiStayAwake(stayAwakeConditions, pluggedType)) {
long triggerTime = System.currentTimeMillis() + idleMillis;
mAlARMManager.set(AlARMManager.RTC_WAKEUP, triggerTime, mIdleIntent);
mPluggedType = pluggedType;
return;
}
mPluggedType = pluggedType;
}
o StatusBarPolicy用来更新状态栏上的充电图标。
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
updateBattery(intent);
}
一、BATTERY相关广播
1.Intent.ACTION_BATTERY_CHANGED 电量状态更新
包括下面的信息。
“status”(int类型)…状态,定义值是BatteryManager.BATTERY_STATUS_XXX。
“health”(int类型)…健康,定义值是BatteryManager.BATTERY_HEALTH_XXX。
“present”(boolean类型)
“level”(int类型)…电池剩余容量
“scale”(int类型)…电池最大值。通常为100。
“icon-small”(int类型)…图标ID。
“plugged”(int类型)…连接的电源插座,定义值是BatteryManager.BATTERY_PLUGGED_XXX。
“voltage”(int类型)…mV。
“temperature”(int类型)…温度,0.1度单位。例如 表示197的时候,意思为19.7度。
“technology”(String类型)…电池类型,例如,Li-ion等等。
2.Intent.ACTION_BATTERY_LOW //表示电池电量低
3.Intent.ACTION_BATTERY_OKAY //表示电池电量充足,即从电池电量低变化到饱满时会发出广播
二、监听UEventObserver,读取sysfs里中的状态
private UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
String strOnline = event.get("POWER_SUPPLY_ONLINE"); //电源连接状态
String strBatteryState = event.get("POWER_SUPPLY_STATUS");
//电池状态,"Discharging","Charging","Not charging","Full","Unknown"
String strBatteryLevel = event.get("POWER_SUPPLY_CAPACITY"); //电池剩余容量
...
}
}
1.BatteryService通过JNI(com_android_server_BatteryService.cpp)读取数据。BatteryService通过JNI注册的不仅有函数,还有变量。 如下:
//##############在BatteryService.java中声明的变量################
private boolean mAcOnline;
private boolean mUsbOnline;
private int mBatteryStatus;
private int mBatteryHealth;
private boolean mBatteryPresent;
private int mBatteryLevel;
private int mBatteryVoltage;
private int mBatteryTemperature;
private String mBatteryTechnology;
2.在BatteryService.java中声明的变量,在com_android_server_BatteryService.cpp 中共用,即在com_android_server_BatteryService.cpp中其实操作的也是BatteryService.java中声明的变量
gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");
gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z");
gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I");
gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I");
gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z");
gFieldIds.mBatteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, "mBatteryTechnology", "Ljava/lang/String;");
gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, "mBatteryVoltage", "I");
gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, "mBatteryTemperature", "I");
3.上面这些变量的值,对应是从下面的文件中读取的,一个文件存储一个数值。
#define AC_ONLINE_PATH "/sys/class/power_supply/ac/online" AC电源连接状态
#define USB_ONLINE_PATH "/sys/class/power_supply/usb/online" USB电源连接状态
#define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status" 充电状态
#define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health" 电池状态
#define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present" 使用状态
#define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity" 电池level
#define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol" 电池电压
#define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp" 电池温度
#define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology" 电池技术
android\kernel\kernel\drivers\power\88pm860x_battery.c
pm860x_changed_work
struct pm860x_battery_info *info = container_of(work,
struct pm860x_battery_info, changed_work.work);
pm860x_update_charge_state(info);
power_supply_changed(&info->battery);
MONITOR_INTERVAL
分享到:
相关推荐
使用蓝牙BLE电池服务profile的开发者需要遵守蓝牙SIG的版权和使用条款,这些条款规定了如何使用和分发与规范相关的知识产权。只有蓝牙SIG的成员才能根据会员协议使用和实施这些规范,包括推广者、采用者和关联成员。...
在Android系统中,获取电池电量信息是通过BatteryService这一核心服务来实现的。BatteryService是一个系统级别的服务,它运行在system_process进程中,并在系统启动时由SystemServer初始化并启动。在`SystemServer....
- **上层Service**:监听UEVENT并读取battery相关文件节点,获取电量信息。 - **Bat_thread**:通过10秒定时器更新battery相关信息,电量算法得到的数据会经过进一步处理以适应特殊情况。 - **插拔充电器触发中断**...
Android电池管理通过BatteryService实现了对电池状态的精细控制和监控。它不仅利用了uevent机制来实时响应电池状态变化,还通过sysfs文件系统与内核驱动紧密协作,确保了上层应用能够及时准确地获取电池信息。这一...
"Android应用源码battery(电池)监控程序.zip"提供了一种实现电池状态监控的方法,这可以帮助开发者了解应用对电池寿命的影响,优化应用性能,或者创建专门的电池管理工具。下面,我们将深入探讨Android电池监控的...
系统中的BatteryService会监控电池状态,当检测到设备正在充电时,会向SystemUI发送更新通知。SystemUI接收到通知后,根据预设的动画效果进行绘制。 4. **动画修改** 要修改锁屏充电动画,开发者需要对Android源码...
BatteryService是电池服务的核心,负责监听底层上报的电池事件,并将最新的电池数据通过广播的形式上报给系统。系统一旦接收到新的电池信息,将根据这些信息更新电池显示状态和剩余电量等。 ActivityManagerService...
它包含了一系列的常量,这些常量对应着电池的不同状态,如BATTERY_STATUS_CHARGING(充电中)、BATTERY_STATUS_DISCHARGING(放电中)等。要使用BatteryManager,你需要在代码中引入以下依赖: ```java import ...
1. **BatteryService**: 在Android系统中,`BatteryService` 是一个关键组件,负责收集电池状态信息并更新到系统服务中。它定期从硬件接口获取电池信息,如电量、温度、电压等,并通过`BatteryManager`接口提供给...
5. **后台运行与服务**:为了实现持续监控,BatteryDog会创建一个后台服务(`BatteryService`)。服务在后台运行,即使应用被关闭也能继续工作。服务的生命周期管理和数据同步是源码中的关键部分。 6. **权限管理**...
通过调用`Context.getSystemService(BATTERY_SERVICE)`方法获取BatteryManager实例,然后通过对应的常量(如BATTERY_LEVEL、BATTERY_STATUS等)查询电池状态。 其次,为了实时监控电池状态,可以注册...
2. **BatteryManager**: `BatteryManager`是Android提供的一个系统服务接口,可以获取到关于电池的各种信息,如电量、充电状态、温度、电压等。通过`getBatteryInfo()`方法,我们可以获取到一个`BatteryStatus`对象...
- 充电宝应用可能包含`Service`,用于在后台执行电池相关的任务,比如监控电量、优化电池使用等。Service可以长时间运行,即使用户离开应用界面。 5. **BroadcastReceiver**: - Android的`BroadcastReceiver`...
本项目源码集合包含了电池监控程序的完整实现,对于学习Android开发,特别是系统级服务和传感器数据处理的开发者来说,这是一个宝贵的资源。 首先,我们来探讨电池监控的基本原理。在Android系统中,电池状态信息...
在实现电池监控时,开发者通常会创建一个后台服务或者使用工作调度器(如`WorkManager`或`JobScheduler`),定期检查电池状态。这样做可以确保即使在应用不活跃时也能获取到电池信息。源码中可能包含了这类服务的...
这份“安卓Android源码——battery(电池)监控程序.rar”压缩包包含了实现这一功能的相关源代码,对于开发者来说,深入研究这些源码可以提升对Android系统电池管理机制的理解。 1. **电池状态API**: Android提供了...