Flutter锁屏通知:如何兼顾全屏意图与解锁验证需求?
核心思路
别在AndroidManifest.xml的<application>标签全局设置android:showWhenLocked="true"——这个全局配置会让所有通知都跳过解锁验证。正确做法是仅给全屏意图对应的Activity单独添加该属性,同时为普通通知配置强制解锁的参数,实现两种场景的区分处理。
具体操作步骤
1. 移除全局的showWhenLocked配置
打开android/app/src/main/AndroidManifest.xml,删除<application>标签内的android:showWhenLocked="true"(如果之前添加过的话)。
2. 给全屏意图的目标Activity单独配置属性
如果全屏通知需要打开自定义的原生Activity(比如专门的全屏通知页面),在该Activity的标签中添加以下属性:
<activity android:name=".FullScreenNotificationActivity" android:showWhenLocked="true" android:turnScreenOn="true" />
如果全屏意图直接打开Flutter主Activity,也可以给主Activity添加上述两个属性,后续通过代码区分普通通知的解锁要求。
3. 在Flutter中区分配置两类通知
使用flutter_local_notifications库时,分别为全屏通知和普通通知设置不同参数:
全屏通知配置
创建全屏通知时,必须开启fullScreenIntent: true,同时确保对应的Activity已配置showWhenLocked:
await flutterLocalNotificationsPlugin.show( 0, "紧急通知", "这是全屏通知内容", NotificationDetails( android: AndroidNotificationDetails( 'full_screen_channel', '全屏通知频道', channelDescription: '用于显示全屏紧急通知', priority: Priority.high, importance: Importance.max, fullScreenIntent: true, visibility: NotificationVisibility.public, // 确保锁屏状态下能看到通知内容 ), ), payload: 'full_screen_payload', // 用来标记是全屏通知触发的应用打开 );
普通通知配置
普通通知需将visibility设为NotificationVisibility.private,且不开启fullScreenIntent,这样点击时会触发解锁验证:
await flutterLocalNotificationsPlugin.show( 1, "普通通知", "这是普通通知内容", NotificationDetails( android: AndroidNotificationDetails( 'normal_channel', '普通通知频道', channelDescription: '用于显示普通通知', priority: Priority.default, importance: Importance.default, visibility: NotificationVisibility.private, // 锁屏隐藏内容,点击需解锁 // 不要设置fullScreenIntent ), ), payload: 'normal_payload', );
4. (可选)主Activity的解锁逻辑补充
如果全屏意图打开的是Flutter主Activity,可在原生代码中判断应用打开的来源,对普通通知触发的打开强制要求解锁。比如在MainActivity.kt中添加:
override fun onResume() { super.onResume() val payload = intent.getStringExtra("payload") // 非全屏通知触发的打开,检查锁屏状态并弹出解锁框 if (payload != "full_screen_payload") { val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager if (keyguardManager.isKeyguardLocked) { val unlockIntent = keyguardManager.createConfirmDeviceCredentialIntent("需要解锁", "请解锁以打开应用") startActivityForResult(unlockIntent, 1001) } } }
通过以上设置,就能同时实现:全屏通知在锁屏时直接显示,普通通知点击必须完成解锁才能进入应用。
内容的提问来源于stack exchange,提问作者Hanna

