Notifier 通知扩展:功能强大的Android通知管理工具,支持通知通道、意图、闹钟和多种通知类型

« 返回首页

Notifier 通知扩展

下载

.aix拓展文件:

de.ullisroboterseite.ursai2notification.aix

.aia示例文件:

SimpleNotificationTest.aia

ExtendedNotificationTest.aia

ProgressBarTest.aia

NotificationAlarmTest.aia

RememberUrs.aia

KeepAwake_Notification.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 扩展时,意图类型 EventUrsNotification.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允许在设备级别、通道级别和通知本身进行设置。

通知的许多属性,例如重要性或振动模式,都是在通道级别设置的。这些属性由应用程序在创建通道时定义,之后无法更改。用户对大多数通道属性拥有完全访问权限,可以随意修改。用户进行的修改不应被覆盖。因此,创建后程序无法通过设置更改属性。即使删除通道然后重新创建,它也会使用最后可用的设置创建。”擦除”实际上只是隐藏。只有通道的 NameDescription 属性可以稍后更改。否则纠正拼写错误是不可能的。

如果要更改属性,必须使用新的通道ID(新的通道ID)。启动应用程序时,可以使用 UrsAI2NotificationChannel.HideChannel 隐藏现有通道。

因此,您应该仔细考虑将哪些属性分配给通道。

关于意图 Intent

Android使用Intent对象向系统发送命令。Intent包含执行指定操作所需的所有信息。例如,AI2的ActivityStarter在内部使用Intents来启动其他应用程序。

关于闹钟 Alarms

闹钟是在特定时间(闹钟时间)触发的操作。它们链接到一个Intent,指定闹钟时间要执行的操作。

闹钟可以被创建和删除。没有特殊的修改功能。闹钟具有唯一的ID(RequestCode)。如果在触发前一个闹钟之前使用相同ID创建第二个闹钟,现有闹钟将被更新。

Android没有获取活动闹钟的方法。如有必要,程序本身必须跟踪它创建了哪些闹钟。

关于BackStack(活动堆栈)

BackStack图示

Android在堆栈中管理相继启动的活动。在App Inventor中,Activity要么是通过ActivityStarter组件调用的Screen,要么是其他应用程序。

Top Activity是当前显示在Android设备显示屏上的Screen。Base Activity是应用程序启动时的Screen,即Screen1。

每次通过 Control.open another screenControl.open another screen with start 指令打开新的Screen时,都会创建新的Activity并成为新的Top Activity。如果用户按下Back按钮(因此得名BackStack)或执行 Control.close screenControl.close screen with plain textControl.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 设置为 HighMax,则会播放声音。其他设置由通道定义。请注意,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

记忆URS

使用通知提醒的实用示例应用程序。

KeepAwake Notification 保持唤醒通知

展示如何使用通知保持设备唤醒的示例。

Notifier 示例 - Remember URS

下载

.aia示例文件:

RememberUrs.aia

示例概述

Remember URS 示例图标

示例说明

此示例展示如何编程提醒功能。目的是诱导用户定期打开应用程序。

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

相关参考

文档反馈