- Notifier 通知扩展
- Notifier 示例 - Remember URS
Notifier 通知扩展
下载
.aix拓展文件:
de.ullisroboterseite.ursai2notification.aix
.aia示例文件:
版本历史
| 版本 | 修改内容 |
|---|---|
| 1.0 (2020-09-07) | 初始版本 |
| 2.0 (2021-03-08) | 完全修订和扩展版本 |
| 2.1 (2021-03-16) | 某些方法声明为 public,以便 KeepAlive 扩展可以调用它们(对功能无影响) |
| 2.2 (2021-03-20) | 意图ID未正确传递到OnClick事件 |
| 2.3 (2021-04-05) | 通知属性 NumberID 的显示与内部默认值不匹配(注意:示例不受影响,仍包含扩展的2.2版本) |
| 2.4 (2021-04-16) | - 设计器中 Colorized 属性的数据类型错误- 使用 KeepAlive 扩展时,意图类型 Event 的 UrsNotification.OnClick 事件未触发(注意:示例不受影响) |
| 2.5 (2021-04-17) | 在某些条件下,UrsNotification.Onclick 事件只触发一次 |
| 2.6 (2021-05-12) | 如果更改了包名,启动AI2应用(意图类型 Screen)在Kodular上无法工作 |
| 2.7 (2021-05-15) | 如果更改了包名,启动AI2应用(意图类型 Screen)在Kodular上无法工作添加了 GetActiveNotifications |
| 2.8 (2021-06-13) | LauncherIntent 中的 FlagNewTask 属性被忽略但Android 10需要FlagNewTask 属性的默认值更改为 true |
| 2.9.1 (2022-10-13) | 适配SDK31(Android 12): 所有 PendingIntent 获得 FLAG_IMMUTABLE 标志请求 android.permission.SCHEDULE_EXACT_ALARM 权限捕获全局异常并写入日志 |
| 2.10 (2023-11-23) | 适配SDK33(Android 13): 需要 POST_NOTIFICATIONS 权限才能显示通知添加 AreNotificationsEnabled 方法添加 OpenNotificationSettings 方法添加 AreNotificationsPaused 方法 |
| 2.11 (2024-09-04) | 适配Android 14 |
| 2.12 (2024-10-26) | 修复使用多个Intent实例时的错误 |
| 2.13 (2024-11-03) | - 添加 OnNewIntent 事件- 添加 IsRunningInCompanion 属性- 修改设计器属性的 PropertyCategories,使扩展与Kodular兼容- 某些代码区域的内部重构 |
| 2.14 (2025-10-04) | - 添加 UrsAI2NotificationChannel.RequestNotificationPermission 方法- 添加 UrsAI2NotificationChannel.OnNotificationPermissionResponse 事件- 重新设计 UrsAI2NotificationChannel.OpenNotificationSettings 方法。直接检查频道的权限无法正常工作参见”关于权限”部分 |
⚠️ 注意:不保证所有示例都使用了扩展的最新版本。尝试示例时,如有必要应重新加载最新版本。
关于通知
通知概述可在Android文档中查看:通知概述。
通知在单独的窗口(通知面板)中显示,与应用程序分离。它们可以被创建和删除。没有特殊的修改功能。通知具有唯一的ID(NumberID)。如果在删除前一个通知之前使用相同ID创建第二个通知,现有通知将被更新。
Android没有获取活动通知的方法。如有必要,程序本身必须跟踪它创建了哪些通知。
此扩展可以生成的通知具有以下结构(不需要显示所有元素):

所有文本元素都可以用HTML标签格式化。可以使用哪些HTML标签取决于Android系统的实现。有关提示,请参见:
关于权限
Android 13(SDK版本33)引入了 Manifest.permission.POST_NOTIFICATIONS 权限。必须授予此权限才能显示通知。安装应用程序后,权限默认设置为 denied(拒绝)。Manifest.permission.POST_NOTIFICATIONS 被分类为危险(保护级别:dangerous)。这意味着用户必须明确授予权限。他们可以通过应用程序设置手动执行此操作。他们也可以撤销权限或覆盖某些属性,例如禁止或允许播放通知声音。
UrsAI2NotificationChannel.AreNotificationsEnabled 属性指示是否已授予显示通知的一般权限。UrsAI2NotificationChannel.OpenNotificationSettings 方法打开可用于设置与应用通知相关的所有属性的对话框。UrsAI2NotificationChannel.RequestNotificationPermission 打开提示用户授予显示通知的一般权限的对话框。此提示的结果通过 UrsAI2NotificationChannel.OnNotificationPermissionResponse 事件返回。如果用户授予权限,它最初适用于应用程序的所有频道。
注意:此权限指定应用程序是否允许显示消息。用户可以为个别频道配置不同的设置。这在当前Android版本(Android 16)中无法检查。
关于通知通道
随着API级别26(版本 Oreo 8.0),Android引入了通知通道概念,在某些设备上也称为通知类别。所有通知都必须分配一个通道。
通知概念相当复杂。Android允许在设备级别、通道级别和通知本身进行设置。
通知的许多属性,例如重要性或振动模式,都是在通道级别设置的。这些属性由应用程序在创建通道时定义,之后无法更改。用户对大多数通道属性拥有完全访问权限,可以随意修改。用户进行的修改不应被覆盖。因此,创建后程序无法通过设置更改属性。即使删除通道然后重新创建,它也会使用最后可用的设置创建。”擦除”实际上只是隐藏。只有通道的 Name 和 Description 属性可以稍后更改。否则纠正拼写错误是不可能的。
如果要更改属性,必须使用新的通道ID(新的通道ID)。启动应用程序时,可以使用 UrsAI2NotificationChannel.HideChannel 隐藏现有通道。
因此,您应该仔细考虑将哪些属性分配给通道。
关于意图 Intent
Android使用Intent对象向系统发送命令。Intent包含执行指定操作所需的所有信息。例如,AI2的ActivityStarter在内部使用Intents来启动其他应用程序。
关于闹钟 Alarms
闹钟是在特定时间(闹钟时间)触发的操作。它们链接到一个Intent,指定闹钟时间要执行的操作。
闹钟可以被创建和删除。没有特殊的修改功能。闹钟具有唯一的ID(RequestCode)。如果在触发前一个闹钟之前使用相同ID创建第二个闹钟,现有闹钟将被更新。
Android没有获取活动闹钟的方法。如有必要,程序本身必须跟踪它创建了哪些闹钟。
关于BackStack(活动堆栈)

Android在堆栈中管理相继启动的活动。在App Inventor中,Activity要么是通过ActivityStarter组件调用的Screen,要么是其他应用程序。
Top Activity是当前显示在Android设备显示屏上的Screen。Base Activity是应用程序启动时的Screen,即Screen1。
每次通过 Control.open another screen 或 Control.open another screen with start 指令打开新的Screen时,都会创建新的Activity并成为新的Top Activity。如果用户按下Back按钮(因此得名BackStack)或执行 Control.close screen、Control.close screen with plain text 或 Control.close screen with value 指令,Top Activity将从堆栈中移除并销毁。它下面的Activity成为新的Top Activity并显示在屏幕上。
堆栈中的活动通常是相互独立的。Activity不知道堆栈中上方或下方是否有其他活动。作为规则,它也不知道另一个活动是否已关闭。只有通过某些事件,它才知道当前是否正在显示或可以进行条目(参见Activity生命周期)。
这在App Inventor中有所不同。有 Screen.OtherScreenClosed 事件,它告诉Screen之前打开的Screen已关闭。它的工作原理如下:
您可以启动新的Activity以获取服务,例如拍摄相机照片。Android为此提供了 startActivityForResult 函数。启动的Activity返回的结果通过操作系统通过 onActivityResult 回调函数传递。调用此函数还表示新启动的Activity已结束。
App Inventor总是使用此函数创建新的Screen和回调函数来触发 Screen.OtherScreenClosed 事件。在内部,App Inventor将最后打开的Screen的名称存储在变量中。它的名称也作为参数在事件中提供。
只要不干扰BackStack的管理,这就能完美工作。然而,在使用Notifications时这是可能和常见的。创建Notification时,以Intent的形式告诉Android(参见”关于意图”)当通知本身或某个操作按钮被点击时应该发生什么。通常要启动新的Activity或将现有的Activity带到前台。例如,如果活动在堆栈中间,您需要指定对堆栈其余部分应该发生什么。很容易想象 startActivityForResult-onActivityResult 机制会感到困惑。具体来说,这意味着 Screen.OtherScreenClosed 事件不会被触发、不再可靠触发或以错误的值触发。因此,您需要非常仔细地考虑应用程序如何与通知交互。
如果使用Notification打开应用程序的Screen或将其带到前台,如果Screen是新创建的,则在Screen中触发 Screen.Initialize 事件。Screen的字段被赋予默认值。如果Screen已经打开并且只是被带到前台,则会触发 UrsNotification.OnNewIntent 事件。
应该发生什么由意图的标志(Intent.Flags及其后续)决定。不幸的是,我无法详细解释如何设置标志以触发某些行为。Intent的文档相当简短,更详细的解释广泛分散。每个人都必须自己阅读和尝试。Valera创建了以下表格,很好地描述了标志的效果:
| 标志 | 含义 | 用法 |
|---|---|---|
| FLAG_CLEAR_TASK | 当在新任务中启动活动时,通过删除堆栈中的所有活动来删除当前任务。参见 FLAG_NEW_TASK | 用于创建新任务批次,如果要完全替换当前屏幕 |
| FLAG_CLEAR_TOP | 如果指定的活动已在堆栈中,则删除其上方的所有活动,并使其成为顶部活动 | 如果要返回特定屏幕同时从堆栈中移除所有中间屏幕,这很有用 |
| FLAG_EXCLUDE_FROM_RECENTS | 将活动从最近使用的应用程序列表中排除 | 用于不应显示在最近使用的屏幕列表中的临时或机密屏幕 |
| FLAG_NEW_TASK | 在新任务堆栈中启动活动 | 如果活动要独立于当前任务流存在,这很有用 |
| FLAG_NO_ANIMATION | 在切换到或离开活动时停用动画 | 当需要立即转换而不需要动画时使用,例如确认屏幕 |
| FLAG_NO_HISTORY | 活动不保存在任务堆栈中,离开后立即销毁 | 适用于不需要保存在历史记录中的临时屏幕,如登录窗口 |
| FLAG_PREVIOUS_IS_TOP | 不再支持 用于在关闭当前活动时将前一个活动返回到堆栈顶部 | 曾在早期Android版本中用于管理任务堆栈 |
| FLAG_REORDER_TO_FRONT | 将现有活动移动到堆栈顶部而不创建新实例 | 适用于返回到已打开的屏幕。其状态被保留 |
| FLAG_RESET_TASK_IF_NEEDED | 如果任务被移动到前台,如果需要正确恢复堆栈,则重新启动活动 | 由系统用于在应用程序之间的过渡期间管理任务 |
| FLAG_SINGLE_TOP | 如果活动已在堆栈顶部,则防止创建活动的副本 | 用于避免在活动已激活时复制屏幕,例如通知屏幕 |
| FLAG_TASK_ON_HOME | 将任务固定为”启动屏幕” - 将其移动到主任务堆栈的位置 | 用于在按下Home按钮时使单独的任务流程表现得像主应用程序屏幕 |
使用方法
App Inventor扩展 UrsAi2Notification 支持创建Android通知。扩展包含三个组件:
-
UrsAI2NotificationChannel(参考)是
NotificationChannel的包装器。使用此组件,可以设置通知通道的属性并可以创建通知。它们可以立即显示、延迟或在特定时间显示。 -
UrsNotification(参考)用于定义通知的属性。例如,
UrsAI2NotificationChannel.CreateNotification方法使用此组件的实例创建通知。 -
UrsIntent(参考)指定点击通知时应执行的操作。可以将此组件的实例提交给
UrsAI2NotificationChannel.CreateNotification方法。当点击通知时,执行由组件定义的Intent。
UrsAI2NotificationChannel 组件
⚠️ 注意:Android版本早于 API Level 26 没有通知通道。通知在没有通道的情况下创建。与通道相关的函数无效。
Android NotificationChannel 在启动应用程序后立即自动创建。您不必自己担心。通知通道的属性可以在App Inventor的设计器窗口中设置。由于创建通道后无法更改通道的属性,运行时没有修改方法。
必须特别注意 Importance 级别的设置。通知获得哪些通用(通道无关)设置取决于此级别。如上所述,这依赖于设备制造商。
如果 Importance 设置为 High 或 Max,则会播放声音。其他设置由通道定义。请注意,Android允许用户覆盖这些设置。您可以将 Lights 设置为 true,但如果用户在系统设置中禁用了通知灯,则不会显示。
如果应用程序的 targetSdkVersion 设置为26或更高,则必须为所有通知创建通道。
UrsNotification 组件
用于定义通知的属性。此组件的实例传递给 UrsAI2NotificationChannel.CreateNotification 方法以创建通知。
UrsIntent 组件
指定点击通知时应执行的操作。此组件的实例传递给 UrsAI2NotificationChannel.CreateNotification 方法。
错误处理
错误代码
扩展使用标准的App Inventor错误处理机制。如果发生错误,会触发 Screen.ErrorOccurred 事件。错误代码对应以下情况:
| 错误代码 | 含义 |
|---|---|
| 17001 | 频道ID无效 |
| 17002 | 通知ID无效 |
| 17003 | 意图对象无效 |
| 17004 | 闹钟时间无效 |
| 17005 | 闹钟类型无效 |
| 17006 | 意图类型无效 |
| 17007 | 闹钟延迟无效 |
| 17008 | 闹钟时间在过去 |
| 17009 | 权限被拒绝 |
示例
Simple Notification Test 简单通知测试

演示基本通知功能的简单示例。创建一个包含标题和文本的基本通知。
Extended Notification Test 扩展通知测试

展示高级通知功能的示例,包括大文本、大图片、多个操作按钮等。
Progress Bar Test 进度条测试

演示如何在通知中显示进度条的示例。适用于长时间运行的操作。
Notification Alarm Test 通知闹钟测试

展示如何创建基于闹钟的通知的示例。在指定时间触发通知。
Remember URS 记忆URS

使用通知提醒的实用示例应用程序。
KeepAwake Notification 保持唤醒通知
展示如何使用通知保持设备唤醒的示例。
Notifier 示例 - Remember URS
下载
.aia示例文件:
示例概述

示例说明
此示例展示如何编程提醒功能。目的是诱导用户定期打开应用程序。
需求 Requirements:
- 通知在应用程序关闭后经过定义的时间段后打开
- 如果通知在定义的时间段内被忽略,它会被替换为新的通知,表示更大的紧迫性
- 点击通知时,通知关闭并打开应用程序
- 打开应用程序时,无论是通过通知还是正常启动功能,都应删除任何可能已显示的通知
- 只要应用程序打开并在关闭后的指定时间内(见第1点),就不应出现通知
应用程序状态
应用程序有四个状态:
| 状态 | 应用程序打开 | 待处理 闹钟 |
待处理 第2个闹钟 |
通知 打开 |
第2个通知 打开 |
|---|---|---|---|---|---|
| 1 | X | - | - | - | - |
| 2 | - | X | X | - | - |
| 3 | - | - | X | X | - |
| 4 | - | - | - | - | X |
用户界面
| 应用程序用户界面 | 生成的通知 | |
|---|---|---|
![]() |
![]() |
应用程序没有其他功能。只能关闭它。
组件 Components
项目中使用了以下组件实例:
| 类型 | 名称 | 功能 | |
|---|---|---|---|
| UrsAI2NotificationChannel | Channel | 通知通道 | |
| UrsNotification | AlarmNotification | 闹钟时间要生成的通知 | |
| UrsNotification | UrgentNotification | 稍后更新第一个通知的通知 | |
| UrsIntent | RememberUrsIntent | 打开Screen1的Intent | |
![]() |
Clock | Clock1 | 定期更新闹钟时间的计时器 |
代码 Code
代码不是很复杂。它包含一个创建闹钟或推迟现有闹钟的过程。此函数在应用程序启动时调用一次。生成新闹钟或调整现有闹钟。此函数在闹钟时间到期之前第二次调用,由计时器控制。这会调整现有闹钟,使其不会被触发。当应用程序(主动)关闭时,闹钟时间会再次调整。
您可能认为在应用程序关闭时创建闹钟就足够了。然而,这还不够。如果应用程序外部关闭,例如通过应用程序概览(历史记录),应用程序会识别到这一点。因此不会创建闹钟。这种情况通过在应用程序启动时设置闹钟并重复延迟来覆盖。如果应用程序通过外部机制关闭,常规延迟不再适用,闹钟在预期时间触发。
实际上有两个闹钟。第二个以两倍的延迟时间触发。两个闹钟必须彼此独立存在,因此它们需要不同的ID(RequestCode)。第二个通知旨在更新第一个。为此,两个通知必须具有相同的ID(NumberID)。
理论上,可以使用单个 UrsNotification 实例管理此行为。Channel.CreateAlarm 在调用时从 UrsNotification 对象获取数据。因此,对属性的后续更改不会产生影响。在 CreateAlarm 过程中第二次调用 Channel.CreateAlarm 之前,UrsNotification 实例可以通过代码设置为适合进一步使用,即可以调整标题和文本。但是,由于过程被多次调用,值必须被重置。使用两个实例更容易。
初始化 Screen.Initialize

全局变量 Delay 保存闹钟时间的延迟值(此处为关闭应用程序后10秒)。计时器设置为比延迟时间短的时间(2秒)。可以使用更短的时间,但这会给系统带来压力。任何已显示的通知都将被删除。最后,创建闹钟或调整现有闹钟。
闹钟时间的更新

闹钟时间定期更新和应用程序关闭时更新。
创建闹钟/更新闹钟时间 CreateAlarm 过程

严格来说,有两个闹钟。第二个以两倍的延迟时间创建。
原文:Ullis Roboter Seite - AI2 Notifier Example Remember URS
原文链接
原版英文文档:Ullis Roboter Seite - AI2 Notification



扫码添加客服咨询