Englisch version   English version


Version Anpassungen
1.0 (2020-03-07) Initiale Version
1.1 (2020-07-16) Methoden hinzugefügt (Abschnitt Akku Optimierung, s.u.):
- RequestIgnoreBatteryOptimization
- IsIgnoringBatteryOptimizations
- OpenBatteryOptimizationSettings
1.2 (2020-08-05) Release() hatte keine Wirkung.
1.3 (2020-08-08) Mehrfacher Aufruf von Release führte zu einer Exception.
1.4 (2021-01-26) WifiLock hinzugefügt.
1.5 (2021-03-21)  - Eigenschaften Version und VersionSDK hinzugefügt.
- SDK-Versionsprüfung bei Funktionen zur Einstellung der Akku-Optimierung.
- Fehler bei RequestIgnoreBatteryOptimization behoben.
1.6 (2021-04-09) Methode IsRunningInCompanion hinzugefügt.
Hinweis: Die Beispiele sind nicht betroffen und enthalten noch die Version 1.5 der Extension.
1.7 (2021-07-20) Eigenschaften OnAfterRelease, AcquireCausesWakeup und Methoden AquireFullWakeLock, EnableShowOnLockScreen hinzugefügt.

Motivation

Für manche Projekte ist es notwendig zu verhindern, dass die zugehörige App vom Betriebssystem deaktiviert wird. In frühen Android Versionen war es möglich, einen sogenannten WakeLock zu setzen. Dieser bewirkte, dass die App vom Betriebssystem nicht abgeschaltet wurde.

Mit der Version 6.0 (Marshmallow) hat Android den Doze-Modus zur Optimierung der Akku-Laufzeiten eingeführt. Diese Funktion schaltet, wenn keine App aktiv bedient wird, nach und nach alles herunter (Display, CPU, WiFi, etc.). Auch die WakeLock-Funktion wurde z.T. außer Kraft gesetzt.

Der MIT App Inventor bietet leider keine wirklich funktionierende Möglichkeit, dem Abschalten entgegen zu wirken. Zwar kann man die Komponente Clock als Timer einsetzen und auch einstellen, dass die Events im Hintergrund ausgelöst werden (TimerAlwaysFires). Bei meinem Smartphone mit der Android-Version Oreo 8.1 war jedoch das, was bei bei einem Timer-Event möglich ist, sehr eingeschränkt. Netzwerkfunktionen standen z.B. nicht zur Verfügung.

Mit der hier beschriebenen Extension kann man erreichen, dass die CPU nicht abgeschaltet wird und die App über einen langen Zeitraum aktiv bleibt.

Viele nützliche Hintergrundinformationen findet man im ZEBRA Developer Portal: Keeping your Android application running when the device wants to sleep.


In­halts­ver­zeich­nis

Download

WakeLock

WifiLock

Akku-Optimierung

Referenz

Einstellungen zur Akku-Optimierung

Beispiel

Test

Werkzeuge

Download

Das ZIP-Archiv UrsAI2WakeLock zum Download. Das Archiv enthält den Quellcode, das kompilierte Binary zum Upload in den App Inventor und eine Beispiel-Anwendung.

Hinweis: Die Extension funktioniert nicht im Companion. Dort fehlt die WAKE_LOCK-Permission. Evtl. kann man sich hierüber behelfen: Patchen des AI2 Companion - zusätzliche Permissions.

WakeLock

Im Prinzip geht es um drei Anwendungsfälle:

  1. Zu einem bestimmten Zeitpunkt (auch periodisch) sollen bestimmte Aktionen durchgeführt werden, z.B. sollen Messwerte erfasst und gespeichert werden.
  2. Die App soll auf äußere Ereignisse reagieren, z.B. auf eine eingehende MQTT-Nachricht reagieren.
  3. Das Display soll nicht abdunkeln, z.B. wenn ein Kochrezept angezeigt wird.

Android bietet folgende Lösungsmöglichkeiten für diese Fälle:

  1. Die Klasse AlarmManager bietet die Möglichkeit, das Gerät zu bestimmten Zeitpunkten aufzuwecken und Code auszuführen. Wenn Wiederholungen benötigt werden, kann man den Alarm wiederholt starten. Dies erfolgt recht zuverlässig. Der Alarm wird ausgeführt, wenn die App im Vordergrund oder im Hintergrund läuft. Man kann sogar dafür sorgen, dass der Alarm ausgelöst wird, wenn die App beendet wurde. AI2 bietet diese Möglichkeit leider nicht.

  2. In früheren Android-Versionen konnte dies per WakeLock (Typ: PARTIAL_WAKE_LOCK) geregelt werden. Der funktioniert seit Android 6.2 leider nicht mehr. Alternativ bietet Android den ForegroundSevice an. UrsAI2KeepAlive implementiert diese Option.

  3. Weiter unten wird beschrieben, wie man Android über die Einstellungen so einrichten kann, dass die Akku-Optimierung weitgehend abgeschaltet wird (s. unten Einstellungen zur Akku-Optimierung).

  4. Es verbleiben zwei WakeLock-Varianten. Der Typ SCREEN_BRIGHT_WAKE_LOCK sorgt dafür, dass der Bildschirm in der vollen Helligkeit angezeigt wird, SCREEN_DIM_WAKE_LOCK erlaubt es dem Betriebssystem das Display zu dimmen. Beide Locks sind  wirkungslos, wenn die App in den Hintergrund gestellt wird. Das Display geht aus und die App wird gestoppt. Wenn die App wieder in den Vordergrund gelangt, werden die Locks wieder aktiv, d.h. das Display geht nicht aus.

Android hat seine Powermanagement-Policy häufig geändert. Man sollte also unbedingt testen, ob die hier gemachten Angaben für das eigen Projekt zutreffen.

WifiLock

Ein Wakelock schützt nicht davor, dass die Netzwerk-Verbindung nach einer gewissen Zeit gekappt wird. Hierzu gibt es den WifiLock. Er ermöglicht einer Anwendung, die WLAN-Verbindung aktiv zu halten. Normalerweise wird die WiFi-Hardware ausgeschaltet, wenn der Benutzer das Gerät längere Zeit nicht benutzt hat. Wenn ein WifiLock gesetzt wird, bleibt die Hardware eingeschaltet, bis die Sperre aufgehoben wird.

Akku-Optimierung

Neben den Methoden zur Einrichtung eines WakeLocks bietet Android drei Methoden mit denen auf die Akku Optimierung eingewirkt werden kann. Dazu gibt es die Möglichkeit über die Einstellungen (Settings) die Akku-Optimierung abzuschalten (s. u. Einstellungen zur Akku-Optimierung).

Die Android-Dokumentation verweist auf eine Whitelist. Leider ist mir bei meinem Gerät nicht klar, was die genauen Auswirkungen sind. Die Dinge sind auch nicht stimmig. Vielleicht liegt das auch an der (deutschen) Implementierung von Xiaomi beim Redmi 5. Leider habe ich kein anderes Gerät um das zu überprüfen. Deshalb verweise ich auf die Android-Dokumentation.

Die Methode RequestIgnoreBatteryOptimization fragt beim Anwender an, die Akku-Optimierung für die App auszuschalten. Nach Aufruf der Methode erscheint diese Anfrage:

Den Punkt "Apps & Benachrichtigungen" gibt es bei meinem Gerät nicht :-(

Ob die App auf der Whitelist steht, kann über die Eigenschaft IsIgnoringBatteryOptimizations abgefragt werden. OpenBatteryOptimizationSettings öffnet einen  Dialog, über den die Whitelist manuell gepflegt werden kann.

Referenz

Eigenschaften

AcquireCausesWakeup
Schaltet den Bildschirm ein, wenn der Wakelock gesetzt wird.
IsActive
Gibt an, ob ein WakeLock aktiv ist.
IsIgnoringBatteryOptimizations
Gibt an, ob die App auf der Whitelist steht.
Erst ab SDK-Version 23 (Marshmallow 6.0.1). Bei älteren Version wird false zurück geliefert.
IsRunningInCompanion
True, wenn die App im Companion läuft.
OnAfterRelease
Wenn dieser Wakelock aufgehoben wird, wird Timer der Timer für die Benutzeraktivität zurück gesetzt, damit der Bildschirm etwas länger eingeschaltet bleibt.
Version
Version der Extension.
VersionSDK
Der API-Level der aktuell laufenden Android-Instanz.
WakeLockType
Liefert den Typ des aktuell eingestellten WakeLocks.
0: kein aktiver WakeLock
1: PARTIAL_WAKE_LOCK
2: SCREEN_DIM_WAKE_LOCK
3: SCREEN_BRIGHT_WAKE_LOCK
4: FULL_WAKE_LOCK

Funktionen

AquireFullWakeLock ()
Setzt einen WakeLock des Typs FULL_WAKE_LOCK. Stellt sicher, dass die Hintergrundbeleuchtung des Bildschirms und der Tastatur mit voller Helligkeit eingeschaltet ist. Wenn der Benutzer den Ein-Aus-Schalter drückt, wird FULL_WAKE_LOCK implizit vom System freigegeben, wodurch sowohl der Bildschirm als auch die CPU ausgeschaltet werden (im Kontrast zu einem PARTIAL_WAKE_LOCK).
Wurde bereits ein WakeLock gesetzt, wird dieser zunächst gelöscht.
AquirePartialWakeLock ()
Setzt einen WakeLock des Typs PARTIAL_WAKE_LOCK. Dieser WakeLock hat praktisch keine Auswirkung, wenn er nicht durch andere Maßnahmen unterstützt wird.
Wurde bereits ein WakeLock gesetzt, wird dieser zunächst gelöscht.
AquireScreenBrightWakeLock ()
Setzt einen WakeLock des Typs SCREEN_BRIGHT_WAKE_LOCK. Solange die App im Vordergrund ist, bleibt der Bildschirm hell.
Wurde bereits ein WakeLock gesetzt, wird dieser zunächst gelöscht.
AquireScreenDimWakeLock ()
Setzt einen WakeLock des Typs SCREEN_DIM_WAKE_LOCK. Solange die App im Vordergrund ist, bleibt die App aktiv, der Bildschirm kann abgedunkelt werden.
Wurde bereits ein WakeLock gesetzt, wird dieser zunächst gelöscht.
AquireWifiLock ()
Setzt einen WifiLock.
EnableShowOnLockScreen ()
Sorgt dafür, dass das Fenster auf dem Lock-Screen ohne Eingabe des PINs angezeigt wird. Sollte im Screen.Initialize-Event aufgerufen werden.
OpenBatteryOptimizationSettings ()
Öffnet einen  Dialog, über den die Whitelist manuell gepflegt werden kann.
Erst ab SDK-Version 23 (Marshmallow 6.0.1). Funktionslos in früheren Versionen (siehe Android-Dokumentation: Optimize for Doze and App Standby).
Release ()
Löscht einen aktiven WakeLock. Wenn kein WakeLock aktiv ist, hat diese Methode keine Auswirkung.
ReleaseWifiLock ()
Löscht den WifiLock.
RequestIgnoreBatteryOptimization ()
Öffnet eine Dialoganfrage mit zur Abschaltung der Akku-Optimierung.
Erst ab SDK-Version 23 (Marshmallow 6.0.1). Funktionslos in früheren Versionen (siehe Android-Dokumentation: Optimize for Doze and App Standby).

Einstellungen zur Akku-Optimierung

Android erlaubt es, den Energiesparmodus für einzelne Apps gezielt auszuschalten. Hier die Anleitung für mein Smartphone (Xiaomi Redmi 5 Plus) mit Android Oreo 8.1:

settings  

App Einstellungen, dort im Suchfeld "akku" eingeben

"Akku-Optimierung auswählen.

settings   "App-Energiesparen auswählen.
settings   Die betreffende App auswählen.

Wenn die betreffende App gestartet ist, findet man sie unter "Aktive App", sonst in der Liste "Schlafende Apps" darunter. Man kann auch nach der App suchen.
settings   Punkt "Energiesparen auswählen.

Dieser Schritt entfällt bei "Schlafender App".
settings   "Keine Beschränkung" auswählen.

Der Standard-Modus ist "Energiesparmodus". Der bewirkt, dass die App abgeschaltet wird.

Beispiel

Eine kleine Beispiel-App zeigt die Verwendung der Extension (s. Download).

Screenshot

Im oberen Teil wird eine laufenden Uhr angezeigt. Um auch eine im Hintergrund laufende App kontrollieren zu können, wird alle zehn Sekunden ein Broadcast-Paket per UDP mit der aktuellen Uhrzeit versandt.

Über die Schaltflächen können die verschiedenen WakeLocks gesetzt werden. Die Checkbox zeigt an, ob ein WakeLock aktiv ist (Auswertung der Eigenschaft IsActive). Darunter wird angezeigt, welcher Typ WakeLock aktiv ist (Auswertung der Eigenschaft WakeLockType).

Test

Mir der Beispiel-App habe ich folgende Szenarien getestet.

Szenario Ergebnis
Lock-Typ Energiesparmodus  
keiner ein (das ist der Standard nach Installation der App) Dies ist der Regelfall. Das Display wird bei fehlender Bedienung nach etwa zehn Sekunden abgedunkelt und nach weiteren fünf Sekunden abgeschaltet. Die App läuft noch einige Zeit weiter, z.T. einige Minuten. Diese Zeit ist aber nicht fix, sondern war bei jedem Versuch unterschiedlich.
keiner aus (gemäß Anleitung bei "Einstellungen zur Akku-Optimierung") Der Bildschirm wird abgeschaltet, die App sendet jedoch weiter. Die Zeitintervalle werden nicht einhalten, der Versandt der UDP-Pakete erfolgt unregelmäßig.
SCREEN_BRIGHT_WAKE_LOCK
SCREEN_DIM_WAKE_LOCK
unerheblich

Solange die App im Vordergrund ist, bleibt sie aktiv, ggf. wird das Display abgedunkelt. Der Versandt der UDP-Pakete erfolgt zu den vorgegebenen Zeiten.

Wird die App in den Hintergrund verlagert, verhält sich das System wie im Regelfall.

PARTIAL_WAKE_LOCK ein Keine Wirkung, die App verhält sich wie im Regelfall.
aus

Bei App im Vordergrund werden die UDP-Pakete sauber verschickt.

Wird die App in den Hintergrund verschoben, wird der UDP-Versand nach einiger Zeit unregelmäßig.

 

Messungen 1 2 3 4 5 6 7 8
Energiesparmodus: ein ein ein ein aus aus aus aus
Vordergrund (VG)
Hintergrund (HG)
VG HG VG HG VG HG VG HG
PARTIAL_WAKE_LOCK nein nein ja ja nein nein ja ja
  18:59:50
19:01:51
19:03:52
19:04:33
19:04:51
stopp
18:49:10
18:49:20
18:49:44
18:49:51
18:50:35
18:50:40
18:50:51
18:51:40
18:51:52
18:52:30
18:52:44
stopp
19:38:10
19:38:20
19:38:30
19:38:40
19:38:50
19:39:00
19:39:10
19:39:20
19:39:30
19:39:40
19:39:50
19:40:00
19:40:10
19:40:20
19:40:30
19:40:40
19:40:50
19:41:00
19:41:10
19:41:20
19:41:30
stopp
19:54:30
19:54:40
19:54:50
19:55:00
19:55:10
19:55:20
19:55:30
19:56:49
19:57:21
19:58:01
19:58:33
stopp
22:04:02
22:04:20
22:04:59
22:05:00
22:05:31
22:07:22
22:08:01
22:09:14
22:11:52
22:14:10
...
Extrem
unregelmäßig
mit Aussetzern
22:23:04
22:24:05
22:25:06
22:26:06
22:26:30
22:27:07
22:27:22
22:28:59
22:29:00
22:29:15
22:29:31
...
Extrem
unregelmäßig
mit Aussetzern
06:03:00
06:03:10
06:03:20
06:03:30
06:03:40
06:03:50
06:04:00
06:04:10
06:04:20
06:04:30
06:04:40
.....
07:07:20
07:07:30
07:07:40
07:07:50
07:08:00
07:08:10
...
Präzise
07:09:20
07:09:30
07:09:40
07:09:50
07:10:00
07:10:10
07:10:28
07:10:30
07:10:43
....
07:26:20
07:27:06
07:27:22
07:27:41
07:29:14
...
Zuerst präzise,
dann sehr unregelmäßig

Werkzeuge

Für die Erstellung eigener Extensions habe ich einige Tipps zusammengestellt: AI2 FAQ: Extensions entwickeln.