понедельник, 20 февраля 2012 г.

Android Training-Энергосбережение-Отслеживание заряда батареи и состояния зарядки


Чтобы быть хорошим жителем на устройстве, ваше приложение должно ограничивать свое влияние на срок работы батареи. После этого курса вы будете способны создавать приложения, которые отслеживают и изменяют свою функциональность и поведение в зависимости от состояния устройства.
Принимая такие меры, как отключение фонового сервиса загрузки обновлений при потере связи или снижения темпов обновления при низком заряде батареи вы будете уверены в том, что влияние вашего приложения на срок жизни батареи минимально и это делается без ущерба для пользователей.
Отслеживание заряда аккумулятора и состояния зарядки.
Когда вы хотите изменить частоту фоновых обновлений для уменьшения влияния этих обновлений на срок работы аккумулятора, вам стоит начать с проверки текущего уровня заряда аккумулятора и состояния зарядки.
Влияние на срок работы аккумулятора зависит от уровня зарядки и состояния зарядки устройства. Влияние выполняющихся обновлений в то время, когда устройство заряжается от сети незначительно, так что в большинстве случаев вы можете увеличить частоту обновлений для устройства включенного в розетку. И наоборот, если устройство разряжается, уменьшение частоты обновления поможет продлить жизнь аккумулятору.
Кроме этого можно проверять текущий уровень зарядки и уменьшать частоту или даже выключать обновления при почти разряженном аккумуляторе
Определение текущего состояния зарядки.
Начните с определения текущего состояния зарядки. BatteryManager передает все сведения о батарее и зарядке в sticky Intentе, включающем в себя статус зарядки.
Т.к. это sticky intent, нет нужды регистрировать BroadcastReceiver—простым вызовом registerReceiver передаем null как приемник, и получаем intent состояния аккумулятора. Вы можете передать BroadcastReceiver объект тут, но мы будем обрабатывать обновления позже, так что пока это не обязательно.
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);
Вы можете извлечь информацию о текущем состоянии зарядки и, если устройство сейчас заряжается, узнать тип зарядки-от USB или источника переменного тока.
// Заряжаемся или заряжено?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                status == BatteryManager.BATTERY_STATUS_FULL;
// Как мы заряжаемся?
int chargePlug = battery.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;
Обычно вам стоит увеличить скорость фоновых обновлений в случае, если устройство подключено к источнику переменного тока, уменьшить ее при зарядке через USB, и снизить еще больше в состоянии разрядки батареи.
Отслеживание изменений в состоянии зарядки.
Состояние зарядки может легко поменяться при подключении устройства к сети, так что важно отслеживать изменения в состоянии зарядки и изменять частоту обновлений в нашем случае. BatteryManager передает действие каждый раз когда устройство подключается или отключается от сети питания. Важно получать информацию об этих событиях даже когда ваше приложение не работает-эти события должны влиять на то, как часто вы запускаете ваше приложения для запуска фонового обновления-так что вам следует зарегистрировать BroadcastReceiver в manifest-файле для отслеживания обоих событий, путем определения ACTION_POWER_CONNECTED и 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>
В  реализации BroadcastReceiverа вы можете извлечь информацию о текущем состоянии зарядки:
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;
    }
}
Определение уровня заряда батареи.
В некоторых случая также полезно определить текущий уровень зарядки батареи. Вы можете например уменьшить темп обновлений при уровне заряда ниже определенного уровня.
Информацию о текущем уровне зарядки можно получить извлечением информации об текущем уровне батареи и соотношении:
int level = battery.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = battery.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float batteryPct = level / (float)scale;
Отслеживание важных изменений в уровне заряда батареи.
Вы не можете легко постоянно отслеживать уровень заряда аккумулятора, но вам и не нужно это делать.
В общем, постоянное отслеживание уровня заряда батареи может повлиять на этот самый заряд больше, чем обычное поведение программы, так что хорошей практикой будет отслеживать только важные изменения-например когда устройство доходит до уровня низкого заряда аккумулятора или выходит из него.
Пример ниже показывает, как это реализовать при помощи слушанья 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>
В общем случае хорошей практикой будет выключение всех ваших фоновых обновлений при достижении критически низкого уровня заряда батареи-актуальность данных будет не важна если телефон выключится перед тем, как вы получите доступ к ним.


1 комментарий:

  1. Есть удаленная работа, связанная с разработкой ПО под Андроид. Если интересно, то наберите меня +380504218361.

    ОтветитьУдалить