几段重要代码
- 回调获取电池属性,发送广播:
系统底层监测到电量变化,将回调如下函数:
platform/frameworks/base/services/java/com/android/server/BatteryService.java
BatteryListener
private final class BatteryListener extends IBatteryPropertiesListener.Stub {
public void batteryPropertiesChanged(BatteryProperties props) {
BatteryService.this.update(props);
}
}
---->update();
---> processValuesLocked()
----->sendIntentLocked()
系统电量变化,最终调用如下函数:
sendIntentLocked
private void sendIntentLocked() {
// Pack up the values and broadcast them to everyone
final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); //new一个ACTION_BATTERY_CHANGED广播
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_REPLACE_PENDING);
int icon = getIconLocked(mBatteryProps.batteryLevel);
intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryProps.batteryStatus);
intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth);
intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryProps.batteryPresent);
intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryProps.batteryLevel);
intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryProps.batteryVoltage);
intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryProps.batteryTemperature);
intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryProps.batteryTechnology);
intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger); //传递系统电池属性
mHandler.post(new Runnable() {
@Override
public void run() {
ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL); //发送ACTION_BATTERY_CHANGED广播
}
});
}
- 低电量提醒界面:platform\frameworks\base\packages\SystemUI\src\com\android\systemui\power\PowerUI.java
BatteryService.java中的sendIntentLocked() 发送的ACTION_BATTERY_CHANGED,由如下类接收:
PowerUI extends SystemUI
public class PowerUI extends SystemUI {
public void start() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED); //接收ACTION_BATTERY_CHANGED广播
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); //启动名为mIntentReceiver 的receiver,接收ACTION_BATTERY_CHANGED广播
}
private int findBatteryLevelBucket(int level) { //电量不同,返回的值不一样
if (level >= mLowBatteryAlertCloseLevel) {
return 1; //电量正常
}
if (level >= mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryWarningLevel)) {
return 0; //电量介于低电平和正常之间,一般为电量刚刚从低于15%充电到高于15%时,返回此值
}
if (level < mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel)) { //该值在config.xml中定义
return -2; //电量低于15时
}
if (level < mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryWarningLevel)) { //该值在config.xml中定义
return -1; //电量低于5时
}
throw new RuntimeException("not possible!");
}
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { //mIntentReceiver
public void onReceive(Context context, Intent intent) {
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { //收到ACTION_BATTERY_CHANGED广播时
final int oldBatteryLevel = mBatteryLevel; //存储上次电量值
mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100); //mBatteryLevel获取intent传来的最新电量值
int oldBucket = findBatteryLevelBucket(oldBatteryLevel);
int bucket = findBatteryLevelBucket(mBatteryLevel);
if (!plugged //plugged为0,表示电源为完全采用电池
&& (bucket < oldBucket || oldPlugged) //当电量级别改变时或者电源由电池充电状态变为纯电池供电状态时,为真
&& mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN //电池状态不为未知
&& bucket < 0) { //代表电池电量低于15%时
showLowBatteryWarning(); //显示低电量界面
// only play SFX when the dialog comes up or the bucket changes
if (bucket != oldBucket || oldPlugged) {
playLowBatterySound(); //播放低电量声音文件
}
}
}
void showLowBatteryWarning() {
} //低电量界面显示,当前为空,后再详述
}
}
- 电量警告临界值设置:platform/frameworks/base/core/res/res/values/config.xml
电池电量参数
<integer name="config_criticalBatteryWarningLevel">5</integer>
//电池电量为5时,提示一次,低电量界面
<!--Shutdown if the battery temperature exceeds(this value*0.1)Celsius.-->
<integer name="config_shutdownBatteryTemperature">680</integer>
<!--Display low battery warning when battery level dips to this value-->
<integer name="config_lowBatteryWarningLevel">15</integer>
//电池电量为15时,提示一次,低电量界面
<!--Close low battery warning when battery level reaches this value-->
<integer name="config_lowBatteryCloseWarningLevel">20</integer>
//电量为20,电池电量报警临界值
解决方案
- 解决的问题:
电量介于5%~15%时,系统只跳出一次电量低提示框,当电量低于5%时,应再跳出一次电量低提示框。 - 解决:
经过调试,发现问题出现在
PowerUI.java文件中的
private int findBatteryLevelBucket(int level)()函数;
传入电量后,无法正确返回,目前已经重写该函数,结果如上。
参考文档:
android 电池(一):锂电池基本原理篇
android低电量处理流程
android 4.4 电池电量显示分析(低电量提醒与电池图标)Java 层
网友评论