为什么要优化
智能手机基本上每天可以充电一次,但如果一个APP应用消耗太多电力,肯定会有问题。 开发中的电量优化可能最容易被忽视。
如何检测
1、手机安装-查看电池使用情况、功耗;
2、使用电池历史记录配置电池使用情况。
优化方案
监视充电状态和电池电量
确认当前充电状态的intentfilterifilter=newintentfilter (intent.action _ battery _ changed );
intentbatterystatus=context.register receiver (null,ifilter );
只需调用注册接收器接收空值作为接收器来注册broadcast接收器,即可返回到当前电池状态Intent。
//充电状态
int status=battery status.getint extra (battery manager.extra _ status,-1);
booleanischarging=status==battery manager.battery _ status _ charging||
status==battery manager.battery _ status _ full;
log.d('wxl ',' isCharging=' isCharging );
toast.maketext(this,' isCharging=' isCharging,Toast.LENGTH_LONG ).show );
//设备用USB或交流充电器充电
intchargeplug=battery status.getint extra (battery manager.extra _ plugged,-1);
booleanusbcharge=charge plug==battery manager.battery _ plugged _ USB;
booleanaccharge=charge plug==battery manager.battery _ plugged _ AC;
log.d(wxl )、) USBcharge=) USBcharge )、acCharge=' acCharge );
toast.maketext(this,' usbCharge=' usbCharge ',acCharge=' acCharge,Toast.LENGTH_LONG ).show );
监视充电状态的变化
通过在清单文件中注册BroadcastReceiver并在一个Intent过滤器中定义ACTION_POWER_CONNECTED和ACTION_POWER_DISCONNECTED,两个事件都可以
PowerConnectionReceiver
publicclasspowerconnectionreceiverextendsbroadcastreceiver {
@Override
公共void onreceive (上下文上下文,Intent intent ) )
int status=intent.getint extra (battery manager.extra _ status,battery manager.battery _ status _ u u u u u u unknown );
字符串电池状态=' ';
开关(status ) {
casebatterymanager.battery _ status _ charging :
电池状态='充电中';
布雷克;
casebatterymanager.battery _ status _ discharging :
电池状态='放电中';
布雷克;
casebatterymanager.battery _ status _ not _ charging :
电池状态='未充电';
布雷克;
casebatterymanager.battery _ status _ full :
电池状态='充满电';
布雷克;
casebatterymanager.battery _ status _ unknown :
电池状态='未知状态';
布雷克;
}
toast.maketext (上下文,' batteryStatus=' batteryStatus,Toast.LENGTH_LONG ).show );
p>int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_AC);
String chargePlug = "";
switch (plugged) {
case BatteryManager.BATTERY_PLUGGED_AC:
chargePlug = "AC充电";
break;
case BatteryManager.BATTERY_PLUGGED_USB:
chargePlug = "USB充电";
break;
case BatteryManager.BATTERY_PLUGGED_WIRELESS:
chargePlug = "无线充电";
break;
}
Toast.makeText(context, "chargePlug=" + chargePlug, Toast.LENGTH_LONG).show();
}
}
注册
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
this.registerReceiver(new PowerConnectionReceiver(), intentFilter);
监控电池电量变化
清单文件中注册一个 BroadcastReceiver,通过侦听 ACTION_BATTERY_LOW 和 ACTION_BATTERY_OKAY,每当设备电池电量不足或退出不足状态时,便会触发该接收器。
BatteryLevelReceiver
public class BatteryLevelReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//当前剩余电量
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
//电量最大值
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
//电量百分比
float batteryPct = level / (float) scale;
Log.d("wxl", "batteryPct=" + batteryPct);
Toast.makeText(context, "batteryPct=" + batteryPct, Toast.LENGTH_LONG).show();
}
}
注册
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
this.registerReceiver(new BatteryLevelReceiver(), intentFilter);
通常,如果设备连接了交流充电器,您应该最大限度提高后台更新的频率;而如果设备是通过 USB 充电,则应降低更新频率,如果电池正在放电,则应进一步降低更新频率;在电池电量极低时停用所有后台更新。
屏幕保持常亮
当设备从休眠状态中,被应用程序唤醒一瞬间会耗电过多,我们可以保持屏幕常亮来节省电量,代码声明:
//屏幕保持常亮
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//一般不需要人为的去掉 FLAG_KEEP_SCREEN_ON 的 flag,windowManager 会管理好程序进入后台回到前台的的操作
//getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
或者,直接在布局中加上 keepScreenOn=true :
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context="com.wuxiaolong.batterysample.MainActivity">
JobScheduler 使用
需要在稍后的某个时间点或者当满足某个特定的条件时执行一个任务,例如当设备接通电源适配器或者连接到 WIFI,在 API 21,google 提供了一个新叫做 JobScheduler API 的组件来处理这样的场景。JobScheduler API 允许同时执行多个任务,执行某些指定的任务时不需要考虑时机控制引起的电池消耗。官方 demo 地址:https://github.com/googlesamples/android-JobScheduler
低电耗模式和应用待机模式
从 Android 6.0(API 级别 23)开始,Android 引入了两个省电功能,可通过管理应用在设备未连接至电源时的行为方式为用户延长电池寿命。低电耗模式通过在设备长时间处于闲置状态时推迟应用的后台 CPU 和网络 Activity 来减少电池消耗。应用待机模式可推迟用户近期未与之交互的应用的后台网络 Activity。
低电耗模式
如果用户设备未插接电源、处于静止状态一段时间且屏幕关闭,设备会进入低电耗模式。 在低电耗模式下,系统会尝试通过限制应用对网络和 CPU 密集型服务的访问来节省电量。这还可以阻止应用访问网络并推迟其作业、同步和标准闹铃。
在低电耗模式下,您的应用会受到以下限制:暂停访问网络。
系统将忽略 wake locks。
标准 AlarmManager 闹铃(包括 setExact() 和 setWindow())推迟到下一维护时段。如果您需要设置在低电耗模式下触发的闹铃,请使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()。
一般情况下,使用 setAlarmClock() 设置的闹铃将继续触发 — 但系统会在这些闹铃触发之前不久退出低电耗模式。
系统不执行 Wi-Fi 扫描。
系统不允许运行同步适配器。
系统不允许运行 JobScheduler。
低电耗模式很容易影响 AlarmManager 闹铃和定时器管理的 Activity,因为当系统处于低电耗模式时,不会触发 Android 5.1(API 级别 22)或更低版本中的闹铃。
为了帮助您安排闹铃,Android 6.0(API 级别 23)引入了两种新的 AlarmManager 方法:setAndAllowWhileIdle() 和 setExactAndAllowWhileIdle()。通过这些方法,您可以设置即使设备处于低电耗模式也会触发的闹铃。
应用待机模式
应用待机模式允许系统判定应用在用户未主动使用它时处于空闲状态。 当用户有一段时间未触摸应用时,系统便会作出此判定,以下条件均不适用:用户显式启动应用。
应用当前有一个进程位于前台(表现为 Activity 或前台服务形式,或被另一 Activity 或前台服务占用)。
应用生成用户可在锁屏或通知托盘中看到的通知。
当用户将设备插入电源时,系统将从待机状态释放应用,从而让它们可以自由访问网络并执行任何待定作业和同步。 如果设备长时间处于空闲状态,系统将按每天大约一次的频率允许空闲应用访问网络。