Monitorowanie poziomu baterii i stanu ładowania

Jeśli zmieniasz częstotliwość aktualizacji w tle, aby ograniczyć wpływ tych aktualizacji na żywotność baterii, na początek sprawdź bieżący poziom baterii i stan ładowania.

Wpływ aktualizacji aplikacji na żywotność baterii zależy od poziomu baterii i stanu ładowania urządzenia. Wpływ aktualizacji podczas ładowania urządzenia z siecią zasilania jest znikomy, więc w większości przypadków możesz zmaksymalizować częstotliwość odświeżania, gdy urządzenie jest podłączone do ładowarki sieciowej. Jeśli natomiast urządzenie się rozładowuje, zmniejszenie częstotliwości aktualizacji pomaga wydłużyć czas pracy na baterii.

W podobny sposób możesz sprawdzać poziom naładowania baterii i ograniczyć częstotliwość aktualizacji, a nawet ich zatrzymywanie, gdy bateria jest prawie wyczerpana.

Określanie bieżącego stanu ładowania

Zacznij od określenia aktualnego stanu ładowania. BatteryManager przekazuje wszystkie informacje o baterii i ładowanie w formie trwałej ikony Intent, która zawiera informacje o stanie ładowania.

Ponieważ intencja jest przyklejona, nie musisz rejestrować elementu BroadcastReceiver. Wywołując po prostu metodę registerReceiver przekazującą dane przez null jako odbiornik, jak pokazano w następnym fragmencie, zwracana jest bieżąca intencja dotycząca stanu baterii. Możesz tu przekazać faktyczny obiekt BroadcastReceiver, ale aktualizacje zajmiemy się w późniejszej sekcji, więc nie jest to konieczne.

Kotlin

val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
    context.registerReceiver(null, ifilter)
}

Java

IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);

Możesz wyodrębnić bieżący stan ładowania oraz, jeśli urządzenie jest ładowane, np. przez USB lub zasilacz:

Kotlin

val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
val isCharging: Boolean = status == BatteryManager.BATTERY_STATUS_CHARGING
        || status == BatteryManager.BATTERY_STATUS_FULL

// How are we charging?
val chargePlug: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1
val usbCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_USB
val acCharge: Boolean = chargePlug == BatteryManager.BATTERY_PLUGGED_AC

Java

// 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 = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;

Zazwyczaj zalecamy maksymalizować częstotliwość aktualizacji w tle, gdy urządzenie jest podłączone do ładowarki, zmniejszać szybkość ładowania przez USB i zmniejszać ją, gdy bateria się rozładowuje.

Monitorowanie zmian stanu ładowania

Stan ładowania może się zmieniać tak łatwo, jak podłączysz urządzenie, dlatego ważne jest, aby monitorować stan ładowania pod kątem zmian i odpowiednio dostosowywać częstotliwość odświeżania.

BatteryManager transmituje działanie za każdym razem, gdy urządzenie jest podłączone do zasilania lub odłączone od zasilania. Zdarzenia te są ważne nawet wtedy, gdy aplikacja nie jest uruchomiona – w szczególności dlatego, że powinny wpływać na częstotliwość uruchamiania aplikacji w celu zainicjowania aktualizacji w tle. W związku z tym zarejestruj w pliku manifestu zdarzenie BroadcastReceiver, aby nasłuchiwać obu zdarzeń, definiując ACTION_POWER_CONNECTED i ACTION_POWER_DISCONNECTED w filtrze intencji.

<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>

Określanie bieżącego poziomu naładowania baterii

W niektórych przypadkach warto też sprawdzić bieżący poziom baterii. Jeśli poziom naładowania baterii spadnie poniżej określonego poziomu, możesz ograniczyć aktualizacje w tle.

Możesz sprawdzić aktualny poziom naładowania baterii, pobierając jej bieżący poziom i skalując na podstawie intencji jej stanu, jak pokazano tutaj:

Kotlin

val batteryPct: Float? = batteryStatus?.let { intent ->
    val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
    val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
    level * 100 / scale.toFloat()
}

Java

int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

float batteryPct = level * 100 / (float)scale;

Reagowanie na znaczne zmiany poziomu baterii

Nie możesz stale monitorować stanu baterii, ale nie jest to konieczne.

Ogólnie rzecz biorąc, wpływ monitorowania poziomu baterii ma na nią większy wpływ niż normalne działanie aplikacji. Na przykład zarejestrowanie w pliku manifestu funkcji BroadcastReceiver w celu anulowania oczekujących zadań, gdy bateria jest słaba, służy głównie do dalszego rozładowywania baterii (i dlatego nie jest to możliwe od Androida 8.0). Możesz za to wprowadzać ograniczenia dotyczące pracy, które określają, kiedy ma być uruchamiany, co pozwoli systemowi na podjęcie decyzji bez zużywania energii podczas uruchamiania aplikacji.

Zazwyczaj nie uruchamiaj aktualizacji w tle, gdy bateria jest bardzo słaba. Nie ma znaczenia, jak aktualne są dane, jeśli telefon automatycznie się wyłączy, zanim będzie można z nich skorzystać. W tym celu użyj biblioteki WorkManager z ograniczeniem BatteryNotLow, aby określić, że praca nie powinna być wykonywana, gdy bateria jest słaba (oprócz odpowiednich ograniczeń NetworkType).

W wielu przypadkach ładowanie urządzenia zbiega się z umieszczeniem go w stacji dokującej. Na następnej lekcji dowiesz się, jak określić bieżący stan dokowania i monitorować zmiany w dokuwaniu urządzeń.