美文网首页
《Android优化专题》——优化电池续航能力

《Android优化专题》——优化电池续航能力

作者: 罗拙呓 | 来源:发表于2018-04-25 10:53 被阅读0次

    《Android优化专题》——优化电池续航能力

    一、监测设备的电量和充电状态

    在用户充电时,程序做任何操作都不会太受到电量影响,此时就适合做一些下载,刷新数据等耗电操作。

    1. 判断当前充电状态

    BatteryManager会广播Sticky intent,我们不需要注册BroadcastReiver,

    IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    Intent batteryStatus = context.registerReceiver(null, ifilter);
    
    // Are we charging / charged?  
    int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
    boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                         status == BatteryManager.BATTERY_STATUS_FULL;
    
    // How are we charging?  
    int chargePlug = battery.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
    boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
    boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;
    

    通过判断设备此时是不是通过AC充电器,USB充电,不在充电状态三种情况来进行是否耗电操作,通常做法是,在使用AC充电时最大化后台更新操作,在使用USB充电时降低更新操作,不在充电状态时,最小化更新操作。

    2. 监测充电状态的改变

    充电状态随时改变,通过检查充电状态的改变,来改变App的某些行为。我们需要在Manifest文件里面注册一个监听来接收ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED的intent。

    <receiver android:name=".PowerConnectionReceiver">
      <intent-filter>
        <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
        <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
      </intent-filter>
    </receiver>
    
    public class PowerConnectionReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                                status == BatteryManager.BATTERY_STATUS_FULL;
    
            int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
            boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
            boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;
        }
    }
    

    3. 判断当前电池电量

    对于一些情况,获取当前电量对于我们是否要进行某个级别的后台操作十分有意义。我们可以从获取电池状态的intent中提取电池电量和容量信息。

    int level = battery.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
    int scale = battery.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    float batteryPct = level / (float)scale;
    

    4. 检测电量的有效改变

    检测电量的有效改变,包括电量进入低电量模式,充电后离开低电量模式,这两种状态的变更是值得我们关注的。我们仅仅需要监听ACTION_BATTERY_LOW与ACTION_BATTERY_OKAY.

    <receiver android:name=".BatteryLevelReceiver">
    <intent-filter>
      <action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
      <action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
      </intent-filter>
    </receiver>
    

    对于设备进入低电量模式我们要尤其注意,这个时候的任何更新、下载等操作是非常影响用户体验,尤其还有可能下载到一半设备就已经关机了。

    二、判断设备的停驻模式

    Android设备有好几种停驻状态,为设备充电,包括车载模式,家庭模式,数字对战模拟模式。停驻状态与充电状态是非常密切相关联的。

    1. 判断当前停驻状态

    停驻状态的广播内容是sticky intent,所以不需要注册广播

    IntentFilter ifilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
    Intent dockStatus = context.registerReceiver(null, ifilter);
    
    int dockState = battery.getIntExtra(EXTRA_DOCK_STATE, -1);
    boolean isDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
    

    2. 判断当前停驻类型

    • Car
    • Desk
    • Low-End (Analog) Desk:API level 11开始才有
    • High-End (Digital) Desk:API level 11开始才有
    boolean isCar = dockState == EXTRA_DOCK_STATE_CAR;
    boolean isDesk = dockState == EXTRA_DOCK_STATE_DESK ||
                     dockState == EXTRA_DOCK_STATE_LE_DESK ||
                     dockState == EXTRA_DOCK_STATE_HE_DESK;
    

    3. 监测停驻状态或者类型改变

    只需要像下面一样注册监听器

    <action android:name="android.intent.action.ACTION_DOCK_EVENT"/>
    
    

    三、判断并监测网络连接状态

    通过网络的连接状况改变,相应改变app的行为,减少无谓的操作,从而延长设备的续航能力。

    1. 判断当前是否有网络连接

    检查是否有网络连接

    ConnectivityManager cm =
            (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = activeNetwork.isConnectedOrConnecting();
    

    2. 判断连接网络的类型

    分为移动网络,WiMax,Wi-Fi,以太网等连接类型

    boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    
    

    使用移动网络比WI-FI代价更大,多数情况下,移动网络下减少一些数据的获取操作,在有WIFI的情况下才开始。

    3. 监测网络连接的切换

    在manifest文件中注册一个带有action的Receiver

    <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
    

    当然我们也没必要不间断地监听网络改变,我们只需要在完成某件任务时而进行监测即可。

    4. 切换是否开启这些Receivers来提高效率

    通过使用PackageManager来切换任何一个在mainfest定义好的组件开启状态,可以使用下面的方法来开启或者关闭任何一个broadcast receiver:

    ComponentName receiver = new ComponentName(context, myReceiver.class);
    
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP)
    

    如果判断到了网络连接已经断开,可以在这个时候关闭除了网络环境改变之外的所有Receivers

    相关文章

      网友评论

          本文标题:《Android优化专题》——优化电池续航能力

          本文链接:https://www.haomeiwen.com/subject/jtmelftx.html