This extension is obsolete and is no longer maintained.
It has been replaced by UrsAi2KeepAwake, a completely revised and extended version with additional options.
Version | Adjustments |
---|---|
1.0 (2020-08-12) | Initial Version |
1.1 (2020-08-21) | - Touching the Notitication had no effect - Properties NotificationIconAsset and ChannelName added - Methods ChannelDescription, NotificationText, NotificationTitle made changeable - Method UpdateIcon added - Property ChannelID removed |
1.2 (2021-03-16) | - Function renamed: isActive ->
IsActive - AutoStop logic revised. - Error codes reassigned. - Extended options for notification by combining with UrsAI2Notifier extension: ~ Method StartEx added. ~ Method StartExWithChannel added. - The automatic setting of a WakeLock removed. The extension UrsAI2WakeLock offers more options. - For Kodular users: The extension UrsKeepAliveManifest (see below) enables the use of UrsAI2KeepAlive. |
1.3 (2021-03-21) | - ForeGround services were introduced with SDK version 26 (Oreo 8.0). The Start
function has no effect for SDK versions older than 26. - Functions Version and VersionSDK added. |
1.4 (2021-04-05) | Methods StartEx and StartExWithChannel transferred the Notification ID (NumberID) not correctly. |
1.5 (2021-04-09) | Method IsRunningInCompanion added. Note: The examples are not affected and still contain version 1.4 of the extension. |
1.6 (2021-04-17) | If the ForeGroundService cannot be started, the Screen.ErrorOccurred event is triggered with the error number 17035. |
1.7 (2021-04-27) | If the screen name specified in ScreenToOpen does not exist, this led
to a crash. ScreenToOpen did not work with Kodular. |
1.8 (2021-05-15) | The wrong ChannelID was passed at StartExWithChannel. At Kodular this led to a crash. |
1.9 (2022-10-10) | Adapted for SDK31 (Android 12): All PendingIntents get the FLAG_IMMUTABLE flag. The service receives the attribute exported = "true". Global exception is caught and written to the log. |
1.10 (2023-09-22) | Android 13 (SDK 33) requires an additional permission to display notifications. |
Notice this:
The automatic setting of a WakeLock has been removed. There were conflicts with the UrsAI2WakeLock extension. The WakeLock must be created using this extension. This extension offers additional options.
For some projects it is necessary to prevent the app from being deactivated by the operating system. In early Android versions it was possible to aquire a so-called WakeLock to prevent the operating system from destroying the app. With version 6.0 (Marshmallow) Android introduced the doze mode to optimize battery life. If no app is actively in use, this mode gradually switches everything down (display, CPU, WiFi, etc.). The WakeLock function has also been partially disabled. To bypass the doze mode effectively, it is necessary to create a foreground service in addition to a WakeLock. Buit such service can be started only when at the same time notification is applied that is visible to the user.
With version nb184 of the MIT App Inventor it is possible that extensions create services. This extension (UrsAi2KeepAlive) creates a foreground service in combination with a partial WakeLock. This ensures that the CPU is not switched off and the app remains active for a long period of time.
Notes for Kodular users:
Sservices must be declared in the manifest file. At the present time (2021-03-16) Kodular does not evaluate the "@UsesServices" annotation. The UrsKeepAliveManifest extension also included in the download can help. It must also be integrated into the Kodular project. An instance of this extension must be dragged on to any of the screens.
The extension is patched and does not nedd the additional block..
Content
The UrsAI2KeepAlive ZIP-Archiv for download. The archive contains the source code, the compiled binary for uploading to the App Inventor and a sample application.
Note:
Services must be declared in the manifest file. This entry is missing in the Companion (App Inventor and also Kodular). UrsAI2KeepAlive therefore does not work in the Companion. Calling Start... (see below) therefore will give error 17035.
However, the behavior of the notification can be simulated. Like this:
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.
As already mentioned above, the extension creates a ForegroundService which, together with a WakeLock, overrides the Doze mode. This means that the app remains active even if it is moved to the background or the display is shut off. Which all resources are available has not yet been tested.
The extension does not automatically set a WakeLock. A WakeLock and a WifiLock can / should be set using the UrsAI2WakeLock extension.
The extension takes into account that the service is effective for the entire app and not only for a single activity (Screen). Internally, in the Java code, the corresponding objects are declared as static, i.e. the internal fields are the same for all instances of the extension. The consequence is that there is only one ForegroundService per app. Several instances of the extension on one or more Screens all affect the same service.
The functions Start and Stop check before execution whether the state of the extension allows this. Start only starts a new service if no service is currently active. Stop has no effect if no service has been started. Calling the functions multiple times is therefore uncritical, but ineffective. This also applies to multiple instantiations of the extension. The status can be queried at any time using the isActive property.
Depending on which action is assigned to the necessary notification (see below), it may be that another Screen of the app is called without the currently open Screen being closed. If the state of the extension is changed in the newly opened screen, this is not always visible for the other screens. The onResume event is triggered every time the screen belonging to the instance of the extension comes into the foreground. The state of the extension can be queried by IsActive.
It should be noted that only one service can be active at a time. So before a new one can be started, an already active one must first be stopped.
In the newer versions of Android, it is not possible, to create a ForegroundService a user visible notification (Notification). Also this notification must be assigned to a notification channel (NotificationChanel). When the ForegroundService starts, this extension creates a simple Notification and, if necessary, a NotificationChannel. The ID of the Channell (ChannelId) is "KEEPALIVE".
The properties of the channel that are visible to the user are defined via the properties ChannelName and ChannelDescription.
If the simple options of the extension to define the notification properties are not sufficient, the extension UrsAI2Notifier can be integrated. This provides extended options for designing the notification. The documentation for details.
The StartEx method accepts one instance of the UrsNotifiaction and UrsIntent extensions to define the notification properties and the actions to be executed. All functionalities can be used (BigPicture, LargeIcon, AddActionButton, Create (for modification) etc.). The corresponding properties of the UrsAI2KeepAlive extension are not evaluated. The methods to cancel the notification do not work because the notification is tied to the ForegroundService.
The StartExWithChannel method additionally uses an instance of the UrsAI2NotificationChannel component to define the notification channel. The channel is automatically created by the component when the app is started. The corresponding properties of the UrsAI2KeepAlive component are not evaluated.
Notifications are usually associated with an action that will be executed when the user clicks the Notification. The ScreenToOpen property can be used to define which action is to be executet. The possibilities are:
Keep the field blank | The notification is not associated with any action. Clicking the notification has no effect. |
A Screen name of the app | When the notification is clicked, the specified Screen of the app opens.The
Screen is started as a new Activity / as
a new Task. The new screen is opened with the start value stored at the StartValue property (see Control.get start value and Control.get plain start text). If the specified Screen does not exist, no ForegroundService is created and the Screen.ErrorOccured event is triggered with the error code 17001. |
A fully qualified Activity name | The specified Activity is started. PackageName and ClassName must be specified. |
A ForegroundService and the associated Notification remains active even if the app is exited by pressing the back button. If the AutoStop property is selected, the extension stops the service when the Screen it belongs to is closed (Android event onDestroy).
This can lead to undesirable behavior and must be taken into account if "Screen1" is specified as the Screen to be opened in ScreenToOpen property. The ForegroundService then maybe stopped at an unexpected time.
Bezeichnung | Typ | Funktion | Voreinstellung | |
---|---|---|---|---|
AutoStop | boolean | The service is stopped automatically when the Screen is closed (see above). | true | |
ChanelDescription | String | Description of the notification channel that is visible to the user (NotificationChanel). This property can be changed later. | -none- | |
ChannelName | String | Name of the notification channel visible to the user (NotificationChanel). This property can be changed later. | "URS KeepAlive" | |
NotificationIcon | String | Name of the system icon for the notification. The possible options are listed in the System System Notification Icons. The icon can be changed using the UpdateIcon method. | "ic_launcher" | |
NotificationIconAsset | Asset | Name of an uploaded file that contains the icon1) to be displayed. This property has priority over the NotificationIcon property. The icon can be changed using the UpdateIcon method. | -none- | |
NotificationText | String | Second line of the Notification. This property can be changed later. | -none- | |
NotificationTitle | String | First line of the Notification. This property can be changed later. | "Keep Alive Service" | |
ScreenToOpen | String | Action that is triggered when the Notification is clicked: - empty: no action - name of a Screen o the app (eg "Screen1"): The screen is opened. - Full name of an Activity (PackageName + ClassName): Start of the Activity. If the activity to be started cannot be found, no action is stored and the Screen.ErrorOccurred event is triggered (see below). |
-none- | |
StartValue | String | AI2 start value, if ScreenToOpen contains a Screen name. | -none- |
1) A size of 96x96 pixel² is recommended for the icon. The icon is displayed in two colors: Transparent areas appear light, colored areas appear dark. If you see a dark square, the graphic probably does not contain any transparent areas.
Block | Function | Comment |
---|---|---|
Starts the service. | Multiple calls are not critical. ForeGround services were introduced with SDK version 26 (Oreo 8.0). The Start function has no effect for SDK versions older than 26. If the ForeGroundService cannot be started, the Screen.ErrorOccurred event is triggered with the error number 17035. |
|
Starts the service. UrsNotificationObject: defines the properties of the notification. UrsIntentObject: defines which action should be triggered when the notification is tapped. |
Multiple calls are not critical. ForeGround services were introduced with SDK version 26 (Oreo 8.0). The StartEx function has no effect for SDK versions older than 26. Neither a ForeGround service is started nor a notification is created. If the ForeGroundService cannot be started, the Screen.ErrorOccurred event is triggered with the error number 17035. |
|
Starts the service. UrsChannelObject: The notification is bound to this channel. UrsNotificationObject: defines the properties of the notification. UrsIntentObject: defines which action should be triggered when the notification is tapped. |
Multiple calls are not critical. If the ForeGroundService cannot be started, the Screen.ErrorOccurred event is triggered with the error number 17035. |
|
Stops the service. | Multiple calls are not critical. | |
Returns whether the service is active. | ||
Gets or sets the user-visible name of the notification channel. | The change also affects notification
channels that have already been created. If the channel has not yet been created (the Start method has never been called), the channel is created. |
|
Gets or sets the user-visible description of the notification. | see above | |
Gets or sets the title of the notification (first line). | The change also affects notifications that have already been displayed. | |
Gets or sets the text of the notification (second line). | The change also affects notifications that have already been displayed. | |
Gets the version of the extension. | ||
Gets the running Android SDK version. | ||
True if the app is running in the companion. | ||
Changes the notification icon. IconName: Either the name of a System Icons or the name of an uploaded file. |
The change affects notifications to be displayed in the future and notifications that have already been displayed. | |
The screen with the instance of the extension comes to the foreground. | See Understand the Activity Lifecycle | |
Is triggered if a non-existent Screen is specified in
ScreenToOpen property. component: Reference of the instance of the extension functionName: "Start" errorNumber: 17001 message: "Screen not found: " + <SscreenToOpen> |
Code | Error text | Meaning |
---|---|---|
17031 | Invalid value at UrsChannelObject. | Wrong type at parameter UrsChannelObject. |
17032 | Invalid value at UrsNotificationObject. | Wrong type at parameter UrsNotificationObject. |
17033 | Invalid value at UrsIntentObject | Wrong type at parameter UrsIntentObject. |
17034 | Screen not found: <screen name> | The specified Screen does not exist. |
17035 | Cannot start ForeGroundService. | Cannot start the foreground service. |
The error codes of the UrsAI2Notifier extension can occur too.
In the following table lists the icons that I found on different internet pages. The appearance is not necessarily the same on every device.
Name | Value | Comment | |
---|---|---|---|
|
alert_dark_frame | 17301504 | |
|
alert_light_frame | 17301505 | |
|
arrow_down_float | 17301506 | |
|
arrow_up_float | 17301507 | |
|
bottom_bar | 17301658 | |
|
btn_default | 17301508 | |
|
btn_default_small | 17301509 | |
|
btn_dialog | 17301527 | |
|
btn_dropdown | 17301510 | |
|
btn_minus | 17301511 | |
|
btn_plus | 17301512 | |
|
btn_radio | 17301513 | |
|
btn_star | 17301514 | |
|
btn_star_big_off | 17301515 | |
|
btn_star_big_on | 17301516 | |
|
button_onoff_indicator_off | 17301518 | |
|
button_onoff_indicator_on | 17301517 | |
|
checkbox_off_background | 17301519 | |
|
checkbox_on_background | 17301520 | |
|
dark_header | 17301521 | Drawable to use as a background for separators on a list with a dark background |
|
dialog_frame | 17301521 | |
|
dialog_holo_dark_frame | 17301682 | |
|
dialog_holo_light_frame | 17301683 | |
|
divider_horizontal_bright | 17301522 | |
|
divider_horizontal_dark | 17301524 | |
|
divider_horizontal_dim_dark | 17301525 | |
|
divider_horizontal_textfield | 17301523 | |
|
edit_text | 17301526 | |
|
editbox_background | 17301528 | |
|
editbox_background_normal | 17301529 | |
|
editbox_dropdown_dark_frame | 17301530 | |
|
editbox_dropdown_light_frame | 17301531 | |
|
gallery_thumb | 17301532 | |
|
ic_btn_speak_now | 17301668 | |
|
ic_delete | 17301533 | |
|
ic_dialog_alert | 17301543 | |
|
ic_dialog_dialer | 17301544 | |
|
ic_dialog_email | 17301545 | |
|
ic_dialog_info | 17301659 | |
|
ic_dialog_map | 17301546 | |
|
ic_input_add | 17301547 | |
|
ic_input_delete | 17301548 | |
|
ic_input_get | 17301549 | |
|
ic_lock_idle_alarm | 17301550 | |
|
ic_lock_idle_charging | 17301534 | |
|
ic_lock_idle_lock | 17301535 | |
|
ic_lock_idle_low_battery | 17301536 | |
|
ic_lock_lock | 17301551 | |
|
ic_lock_power_off | 17301552 | |
|
ic_lock_silent_mode | 17301553 | |
|
ic_lock_silent_mode_off | 17301554 | |
|
ic_media_ff | 17301537 | |
|
ic_media_next | 17301538 | |
|
ic_media_pause | 17301539 | |
|
ic_media_play | 17301540 | |
|
ic_media_previous | 17301541 | |
|
ic_media_rew | 17301542 | |
|
ic_menu_add | 17301555 | |
|
ic_menu_agenda | 17301556 | |
|
ic_menu_always_landscape_portrait | 17301557 | |
|
ic_menu_call | 17301558 | |
|
ic_menu_camera | 17301559 | |
|
ic_menu_close_clear_cancel | 17301560 | |
|
ic_menu_compass | 17301561 | |
|
ic_menu_crop | 17301562 | |
|
ic_menu_day | 17301563 | |
|
ic_menu_delete | 17301564 | |
|
ic_menu_directions | 17301565 | |
|
ic_menu_edit | 17301566 | |
|
ic_menu_gallery | 17301567 | |
|
ic_menu_help | 17301568 | |
|
ic_menu_info_details | 17301569 | |
|
ic_menu_manage | 17301570 | |
|
ic_menu_mapmode | 17301571 | |
|
ic_menu_month | 17301572 | |
|
ic_menu_more | 17301573 | |
|
ic_menu_my_calendar | 17301574 | |
|
ic_menu_mylocation | 17301575 | |
|
ic_menu_myplaces | 17301576 | |
|
ic_menu_preferences | 17301577 | |
|
ic_menu_recent_history | 17301578 | |
|
ic_menu_report_image | 17301579 | |
|
ic_menu_revert | 17301580 | |
|
ic_menu_rotate | 17301581 | |
|
ic_menu_save | 17301582 | |
|
ic_menu_search | 17301583 | |
|
ic_menu_send | 17301584 | |
|
ic_menu_set_as | 17301585 | |
|
ic_menu_share | 17301586 | |
|
ic_menu_slideshow | 17301587 | |
|
ic_menu_sort_alphabetically | 17301660 | |
|
ic_menu_sort_by_size | 17301661 | |
|
ic_menu_today | 17301588 | |
|
ic_menu_upload | 17301589 | |
|
ic_menu_upload_you_tube | 17301590 | |
|
ic_menu_view | 17301591 | |
|
ic_menu_week | 17301592 | |
|
ic_menu_zoom | 17301593 | |
|
ic_notification_clear_all | 17301594 | |
|
ic_notification_overlay | 17301595 | |
|
ic_partial_secure | 17301596 | |
|
ic_popup_disk_full | 17301597 | |
|
ic_popup_reminder | 17301598 | |
|
ic_popup_sync | 17301599 | |
|
ic_search_category_default | 17301600 | |
|
ic_secure | 17301601 | |
|
list_selector_background | 17301602 | |
|
menu_frame | 17301603 | |
|
menu_full_frame | 17301604 | |
|
menuitem_background | 17301605 | |
|
picture_frame | 17301606 | |
|
presence_audio_away | 17301679 | |
|
presence_audio_busy | 17301680 | |
|
presence_audio_online | 17301681 | |
|
presence_away | 17301607 | |
|
presence_busy | 17301608 | |
|
presence_invisible | 17301609 | |
|
presence_offline | 17301610 | |
|
presence_online | 17301611 | |
|
presence_video_away | 17301676 | Presence drawables for videochat or audiochat capable contacts |
|
presence_video_busy | 17301677 | |
|
presence_video_online | 17301678 | |
|
progress_horizontal | 17301612 | |
|
progress_indeterminate_horizontal | 17301613 | |
|
radiobutton_off_background | 17301614 | |
|
radiobutton_on_background | 17301615 | |
|
screen_background_dark | 17301656 | |
|
screen_background_dark_transparent | 17301673 | Semi-transparent background that can be used when placing a dark themed UI on top of some arbitrary background (such as the wallpaper). |
|
screen_background_light | 17301657 | |
|
screen_background_light_transparent | 17301674 | Background drawable that can be used for a transparent activity to be able to display a light UI: this lightens its background to make a light UI more visible. |
|
spinner_background | 17301616 | |
|
spinner_dropdown_background | 17301617 | |
|
star_big_off | 17301619 | |
|
star_big_on | 17301621 | |
|
star_off | 17301618 | |
|
star_on | 17301620 | |
|
stat_notify_call_mute | 17301622 | |
|
stat_notify_chat | 17301623 | |
|
stat_notify_error | 17301624 | |
|
stat_notify_missed_call | 17301631 | |
|
stat_notify_more | 17301625 | |
|
stat_notify_sdcard | 17301626 | |
|
stat_notify_sdcard_prepare | 17301675 | |
|
stat_notify_sdcard_usb | 17301627 | |
|
stat_notify_sync | 17301628 | |
|
stat_notify_sync_noanim | 17301629 | |
|
stat_notify_voicemail | 17301630 | |
|
stat_sys_data_bluetooth | 17301632 | |
|
stat_sys_download | 17301633 | |
|
stat_sys_download_done | 17301634 | |
|
stat_sys_headset | 17301635 | |
|
stat_sys_phone_call | 17301636 | This constant was deprecated in API level 15. Replaced by a private asset in the phone app. |
|
stat_sys_phone_call_forward | 17301637 | This constant was deprecated in API level 15. Replaced by a private asset in the phone app. |
|
stat_sys_phone_call_on_hold | 17301638 | This constant was deprecated in API level 15. Replaced by a private asset in the phone app. |
|
stat_sys_speakerphone | 17301639 | |
|
stat_sys_upload | 17301640 | |
|
stat_sys_upload_done | 17301641 | |
|
stat_sys_vp_phone_call | 17301671 | This constant was deprecated in API level 15. Replaced by a private asset in the phone app. |
|
stat_sys_vp_phone_call_on_hold | 17301672 | This constant was deprecated in API level 15. Replaced by a private asset in the phone app. |
|
stat_sys_warning | 17301642 | |
|
status_bar_item_app_background | 17301643 | |
|
status_bar_item_background | 17301644 | |
|
sym_action_call | 17301645 | |
|
sym_action_chat | 17301646 | |
|
sym_action_email | 17301647 | |
|
sym_call_incoming | 17301648 | |
|
sym_call_missed | 17301649 | |
|
sym_call_outgoing | 17301650 | |
|
sym_contact_card | 17301652 | |
|
sym_def_app_icon | 17301651 | |
|
title_bar | 17301653 | |
|
title_bar_tall | 17301670 | Drawable to use as a background for a taller version of the titlebar |
|
toast_frame | 17301654 | |
|
zoom_plate | 17301655 |
A small sample app shows how to use the extension (see Download). |
|
Screenshot of the app. | |
Screenshot of the Notification. |
The example also contains a project file for a simple UDP receiver. With a second Android device, you can check whether the test app is still active. | |
Screenshot of the simple UDP receiver. |
For developing own extensions I gathered some tips: AI2 FAQ: Develop Extensions.