如何识别用户与推送通知交互的具体屏幕?
区分推送通知交互场景的实现方案
iOS 平台
锁屏/通知栏交互识别
从 iOS 14 开始,系统提供了直接的 API 来区分交互来源。在处理通知响应的代理方法中,你可以通过 UNNotificationResponse 的 origin 属性判断:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { switch response.origin { case .lockScreen: // 用户从锁屏点击通知 print("交互来源:锁屏") case .notificationCenter: // 用户从通知中心点击通知 print("交互来源:通知栏") case .controlCenter: // 用户从控制中心点击通知(iOS 15+) print("交互来源:控制中心") default: break } completionHandler() }
应用角标交互识别
iOS 没有直接监听角标点击的系统 API,因为点击角标的本质是点击应用图标启动/唤醒应用。你可以通过以下方式间接推断:
- 在
application(_:didFinishLaunchingWithOptions:)中,检查启动参数是否包含远程通知信息(UIApplication.LaunchOptionsKey.remoteNotification),同时结合当前应用的未读通知计数(UIApplication.shared.applicationIconBadgeNumber),如果计数大于0且是通过图标点击启动,可间接判断为角标交互。 - 也可以在应用启动后调用
UNUserNotificationCenter.current().getDeliveredNotifications获取当前已投递的通知,结合启动场景辅助判断,但这种方式存在一定误差(用户可能直接点击图标而非角标)。
Android 平台
锁屏/通知栏交互识别
Android 没有直接的系统枚举区分这两个场景,但可以通过以下方式实现识别:
在处理通知点击的 Activity 或 BroadcastReceiver 中,通过 KeyguardManager 检查当前是否处于锁屏状态:
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager if (keyguardManager.isKeyguardLocked || keyguardManager.isDeviceLocked) { // 用户从锁屏点击通知 println("交互来源:锁屏") } else { // 用户从通知栏点击通知 println("交互来源:通知栏") }
注意:该方法需要在 AndroidManifest 中申请 USE_FINGERPRINT 或 USE_BIOMETRIC 权限(针对 Android 10+),否则可能无法准确判断锁屏状态。
应用角标交互识别
和 iOS 类似,点击角标等同于点击应用图标。你可以通过以下方式间接推断:
- 在
MainActivity的onCreate或onNewIntent方法中,检查启动意图的标记(如Intent.FLAG_ACTIVITY_NEW_TASK),同时结合应用的未读通知计数。如果应用是从后台唤醒且存在未读通知,可间接判断为角标交互。 - 部分厂商(如小米、华为)提供了自定义的角标 API,你可以接入厂商 SDK 监听角标点击事件,但这种方式需要适配不同厂商,通用性较差。
通用局限性
- 应用角标交互的识别没有统一的系统级 API,所有方案均为间接推断,存在一定误差。
- 部分低版本系统(iOS <14、Android <10)无法使用上述部分方法,需要做兼容处理。
内容的提问来源于stack exchange,提问作者ElectronAnt
相关产品推荐
相关产品推荐

