Deutsche Version   Deutsche Version


Version Adjustments
1.0 (2020-03-07) Initial version
1.1 (2020-07-16) Methods added (section battery optimization, see below):
- RequestIgnoreBatteryOptimization
- IsIgnoringBatteryOptimizations
- OpenBatteryOptimizationSettings
1.2 (2020-08-05) Release() had no effect.
1.3 (2020-08-08) Calling Release multiple times led to an exception.
1.4 (2021-01-26) WifiLock added.
1.5 (2021-03-21) - Properties Version and VersionSDK added.
- SDK version check for functions for setting the battery optimization.
- Fixed bug with RequestIgnoreBatteryOptimization.
1.6 (2021-04-09) Method IsRunningInCompanion added.
Note: The examples are not affected and still contain version 1.5 of the extension.

Motivation

For some projects it is necessary to prevent the associated app from being deactivated by the operating system. In early Android versions it was possible to set a WakeLock. This ensured that the app was not switched off by the operating system.

With version 6.0 (Marshmallow) Android introduced Doze mode to optimize battery life. If no app is actively used, this function gradually switches down everything  (display, CPU, WiFi, etc.). The WakeLock function has also been partially disabled.

The MIT App Inventor has no functions to prevent the shutdown. You can use the Clock component as a timer and also set the events to be triggered in the background (TimerAlwaysFires). With my smartphone with the Android version Oreo 8.1, however, what could be done within a timer event is very limited. Network functions, for example, are not available

With the extension described here, you can ensure that the CPU is not switched off and the app remains active for a long period of time.

A lot of useful background information can be found in the ZEBRA Developer Portal: Keeping your Android application running when the device wants to sleep.


Content

Download

WakeLock

WifiLock

Battery optimization

Reference

Settings for battery optimization

Example

Test

Tools

Download

The UrsAI2WakeLock ZIP archive for download. The archive contains the source code, the compiled binary for uploading to the App Inventor and a sample application.

WakeLock

In principle, there are three use cases:

  1. At a certain point in time (also periodically) certain actions should be executed, e.g. measured values ​​should be recorded and saved.
  2. The app has to react to external events, e.g. react to an incoming MQTT message.
  3. The display should not go dark, e.g. when a recipe is being displayed.

Android offers the following possible solutions for these cases:

  1. The AlarmManager class offers the option of waking up the device at certain times and executing code. If repetitions are required, the alarm can be started repeatedly. This is done quite reliably. The alarm is triggered when the app is running in the foreground or in the background. You can even arrange for the alarm to go off when the app is closed. Unfortunately, AI2 does not offer this option.

  2. In earlier Android versions this could be controlled via WakeLock (type: PARTIAL_WAKE_LOCK). It no longer works since Android 6.2. Alternatively, Android offers the ForegroundSevice. UrsAI2KeepAlive implements this option.

  3. Below is a description of how you can use the settings to set up Android so that battery optimization is largely switched off (see Settings for battery optimization below).

  4. Two WakeLock variants remain. The type SCREEN_BRIGHT_WAKE_LOCK ensures that the screen is displayed in full brightness, SCREEN_DIM_WAKE_LOCK allows the operating system to dim the display. Both locks have no effect if the app is pushed to the background. The display goes dark and the app stops. When the app comes back to the foreground, the locks are reactivated, i.e. the display keeps bright.

Android has changed its power management policy many times. So you should definitely test whether the information given here applies to your own project.

WifiLock

A Wakelock does not protect against the network connection being cut after a certain period of time. The WifiLock enables an application to keep the WLAN connection active. Typically, the WiFi hardware is turned off when the user has not used the device for a long time. If a WifiLock is set, the hardware keeps switched orunning until the lock is released.

Battery optimization

In addition to the methods for setting up WakeLocks, Android offers three functions to influence the battery optimization by code. You also can switch off the battery optimization via the settings (see below Settings for battery optimization).

The Android documentation refers to a whitelist. With my (German) Xiaomi in the Redmi 5 (German version) I could not verify this. Therefore I refer to the Android documentation.

The RequestIgnoreBatteryOptimization method asks the user to switch off battery optimization for the app. After calling the method, this request appears:

Sorry, no English screenshot. Translated:

Should the app always run in the background?

Allowing "Urs WakeLock Test" to always run in the background can reduce battery life.

You can change this later under "Settings"> Apps & notifications ".

ALLOW REJECT

The IsIgnoringBatteryOptimizations property can be used to query whether the app is on the whitelist. OpenBatteryOptimizationSettings opens a dialog that can be used to manually maintain the whitelist.

Reference

Block Function Annotation
WakeLock
SCREEN_BRIGHT_WAKE_LOCK Sets a WakeLock of the type SCREEN_BRIGHT_WAKE_LOCK. As long as the app is in the foreground, the screen stays bright. If a WakeLock has already been set, it is first deleted.
SCREEN_DIM_WAKE_LOCK  Sets a WakeLock of the type SCREEN_DIM_WAKE_LOCK. As long as the app is in the foreground, the screen remains active but can be darkened. If a WakeLock has already been set, it is first deleted.
PARTIAL_WAKE_LOCK Sets a WakeLock of the type PARTIAL_WAKE_LOCK. This WakeLock has practically no effect if it is not supported by other methods. If a WakeLock has already been set, it is first deleted.
release Releases an active WakeLock. If no WakeLock is active, this method has no effect.
isActive Indicates whether a WakeLock is active. true or false
type Returns the type of the currently set WakeLock. 0: no active WakeLock
1: PARTIAL_WAKE_LOCK
2: SCREEN_DIM_WAKE_LOCK
3: SCREEN_BRIGHT_WAKE_LOCK
WifiLock
WIFI_LOCK Aquires a WifiLock.  
WIFI_LOCK_RELEASE Releases a WifiLock.  
Akku-Optimierung
Request Opens a request to switch off the battery optimization. Since SDK version 23 (Marshmallow 6.0.1). Has no function in previous versions.

see Android-Documentation
Indicates whether the app is on the whitelist.
Opens a dialog that can be used to manually maintain the whitelist.
Other
Gets the version of the extension.  
Gets the running Android SDK version.
True if the app is running in the companion.

Settings for battery optimization

Android allows the energy-saving mode to be switched off specifically for individual apps. Here are the instructions for my smartphone (Xiaomi Redmi 5 Plus) with Android Oreo 8.1:

Sorry, no English instructions :-(

Example

A small sample app shows how to use the extension (see download).

Screenshot

A running clock is displayed in the upper part. In order to be able to control an app running in the background, a broadcast packet is sent every ten seconds via UDP with the current time.

The various WakeLocks can be set using the buttons. The checkbox shows whether a WakeLock is active (evaluation of the IsActive property). In the lower part is shown which type of WakeLock is active (evaluation of the WakeLockType property)

Test

I tested the following scenarios with the example app.

Szenario Result
Lock type power saving mode  
none on (this is the standard after installing the app) This is the default. If it is not operated, the display is darkened after about ten seconds and switched off after another five seconds. The app continues to run for a while, sometimes for a few minutes. However, this time is not fixed and was different for each probe.
none off (according to the instructions under "Settings for battery optimization") The screen turns off, but the app continues broadcasting. The time intervals are not as designated, the UDP packets are sent irregularly.
SCREEN_BRIGHT_WAKE_LOCK
SCREEN_DIM_WAKE_LOCK
irrelevant

As long as the app is in the foreground, it remains active; the display may be darkened. The UDP packets are sent at the specified times.

If the app is moved to the background, the system behaves like the default.

PARTIAL_WAKE_LOCK on No effect, the app behaves like the default
off

If thr the app is in the foreground, the UDP packets are sent regularly.

If the app is moved to the background, the UDP transmission gets irregular after a while.

 

Messungen 1 2 3 4 5 6 7 8
Power saving mode: on on on on off off off off
Foreground (FG)
Background (BG)
FG BG FG BG FG BG FG BG
PARTIAL_WAKE_LOCK no no yes yes no no yes yes
  18:59:50
19:01:51
19:03:52
19:04:33
19:04:51
stop
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
stop
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
stop
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
stop
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
...
Extremely
irregular
with dropouts
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
...
Extremely
irregular
with dropouts
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
...
Precise
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
...
First precise,
then very irregular

Tools

For developing own extensions I gathered some tips: AI2 FAQ: Develop Extensions.