Flutter实现锁屏全屏通知:无需点击自动弹出弹窗
实现Flutter通知触发全屏锁屏弹窗(无需点击通知)
核心思路
要实现无需点击通知就弹出覆盖锁屏的全屏弹窗,关键是利用Android的**全屏Intent(Full Screen Intent)**特性,通过通知触发启动一个专门的全屏Activity,让它直接覆盖锁屏并自动显示。
步骤1:修改通知配置,添加全屏Intent
更新你的scheduleTaskNotification方法,补充全屏Intent相关配置,确保通知渠道的可见性和优先级满足要求:
void scheduleTaskNotification(Task task) async { // 获取Android插件实例,用于创建PendingIntent final androidPlugin = AndroidFlutterLocalNotificationsPlugin(); // 创建启动全屏Activity的PendingIntent final pendingIntent = await androidPlugin.createPendingIntent( task.id!, Intent( action: 'FLUTTER_NOTIFICATION_CLICK', // 替换成你的应用包名和全屏Activity的完整类路径 component: const ComponentName( 'com.your.app.package', 'com.your.app.package.FullScreenNotificationActivity', ), ), ); AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( 'channelId', 'channelName', importance: Importance.max, priority: Priority.high, visibility: NotificationVisibility.public, // 确保锁屏可见 fullScreenIntent: pendingIntent, // 绑定全屏Intent styleInformation: const BigTextStyleInformation(''), ); await _flutterLocalNotificationsPlugin.zonedSchedule( task.id!, task.title, task.note, _convertTime( int.parse(task.startTime.toString().split(':')[0]), int.parse(task.startTime.toString().split(':')[1]), ), NotificationDetails(android: androidNotificationDetails), androidAllowWhileIdle: true, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, matchDateTimeComponents: DateTimeComponents.time, payload: '${task.title} | ${task.note} |', ); }
步骤2:创建Android全屏Activity
在Flutter项目的android/app/src/main/kotlin/com/your/app/package/目录下,新建FullScreenNotificationActivity.kt文件:
package com.your.app.package // 替换成你的应用包名 import android.os.Bundle import android.view.WindowManager import io.flutter.embedding.android.FlutterActivity class FullScreenNotificationActivity : FlutterActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 设置Activity权限:覆盖锁屏、点亮屏幕、解锁键盘 window.addFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD ) // 设置全屏显示 window.decorView.systemUiVisibility = android.view.View.SYSTEM_UI_FLAG_FULLSCREEN } }
步骤3:配置AndroidManifest.xml
在android/app/src/main/AndroidManifest.xml中注册全屏Activity,并添加必要权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.your.app.package"> <!-- 必要权限 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <application ...> <!-- 注册全屏Activity --> <activity android:name=".FullScreenNotificationActivity" android:showOnLockScreen="true" android:showWhenLocked="true" android:turnScreenOn="true" android:launchMode="singleInstance" android:theme="@style/FullScreenNotificationTheme"> </activity> <!-- 原有MainActivity配置... --> </application> </manifest>
然后在android/app/src/main/res/values/styles.xml中添加全屏主题:
<style name="FullScreenNotificationTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowFullscreen">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowBackground">@color/white</item> <!-- 自定义背景色 --> </style>
步骤4:在Flutter中构建弹窗UI
在全屏Activity对应的Flutter页面中,直接显示全屏弹窗。可以通过路由判断启动来源,示例如下:
void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Builder(builder: (context) { // 页面初始化后自动弹出全屏弹窗 WidgetsBinding.instance.addPostFrameCallback((_) { showDialog( context: context, barrierDismissible: false, // 禁止点击外部关闭 builder: (context) => const FullScreenAlert(), ); }); return const Scaffold(body: SizedBox.shrink()); }), ); } } class FullScreenAlert extends StatelessWidget { const FullScreenAlert({super.key}); @override Widget build(BuildContext context) { return SizedBox.expand( child: Container( color: Colors.white, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('任务提醒', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), const SizedBox(height: 20), const Text('这是你的任务通知内容'), const SizedBox(height: 30), ElevatedButton( onPressed: () => Navigator.pop(context), child: const Text('关闭'), ), ], ), ), ); } }
注意事项
- 确保应用包名和Android代码中的包名完全一致。
- Android 13及以上版本需要动态申请
POST_NOTIFICATIONS权限。 - 精确定时通知需要
SCHEDULE_EXACT_ALARM权限,Android 12+可能需要用户手动授权。 - 测试时请将设备设置为锁屏状态,验证弹窗是否正常显示并点亮屏幕。
内容的提问来源于stack exchange,提问作者mkiziltay
相关产品推荐
相关产品推荐

