几段重要代码

  1. 回调获取电池属性,发送广播:
    系统底层监测到电量变化,将回调如下函数:
    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广播            }        });    }
  1. 低电量提醒界面: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() {        }                                                        //低电量界面显示,当前为空,后再详述    }}
  1. 电量警告临界值设置:platform/frameworks/base/core/res/res/values/config.xml

电池电量参数

5                    //电池电量为5时,提示一次,低电量界面68015                    //电池电量为15时,提示一次,低电量界面20               //电量为20,电池电量报警临界值

解决方案

  • 解决的问题:
    电量介于5%~15%时,系统只跳出一次电量低提示框,当电量低于5%时,应再跳出一次电量低提示框。
  • 解决:
    经过调试,发现问题出现在
    PowerUI.java文件中的
    private int findBatteryLevelBucket(int level)()函数;
    传入电量后,无法正确返回,目前已经重写该函数,结果如上。

参考文档:

android 电池(一):锂电池基本原理篇
android低电量处理流程
android 4.4 电池电量显示分析(低电量提醒与电池图标)Java 层

更多相关文章

  1. Android(安卓)显示手机电池的当前电量
  2. android手机电池管理
  3. Android(安卓)电量优化篇
  4. Android中一些常见文件格式分析
  5. 电池寿命:Android“电池”工具是如何工作的
  6. Android设备电量监控
  7. 实时获取Android 各版本电量的统一方法
  8. Android8.1隐藏状态栏电池图标

随机推荐

  1. Android Camera子系统代码流程1
  2. Android实现图片放大缩小
  3. cocos2dx在xcode下开发,编译到android上
  4. Android面试之---谈谈你对Android(安卓)N
  5. android 两点缩放图片
  6. Android 5.0 Input初始化
  7. Android 全屏
  8. Android Build 异常 -android.support.VE
  9. Android百度地图基础实现(标记+GPS)
  10. 用maven创建android的项目。