Flutter本地通知Release模式后台失效及实时追踪中断问题求助
解决方案:Release模式来电通知失效与实时追踪中断问题
一、Release模式下来电通知后台失效修复
1. 修复FCM后台消息处理逻辑
- 给
firebaseMessagingBackgroundHandler添加@pragma('vm:entry-point')注解,防止Release模式下代码被混淆移除:
@pragma('vm:entry-point') Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); // 后台依赖系统通知铃声,不再使用自定义AudioPlayer(后台环境无法加载本地音频资源) showNotification(message); if (message.data['type'] == 'call') { await Future.delayed(const Duration(seconds: 25)); flutterLocalNotificationsPlugin.cancel(message.notification?.hashCode ?? 0); } }
- 调整
showNotification中的来电通知配置,启用系统级铃声和震动,确保后台能触发通知:
AndroidNotificationDetails( 'call_channel', 'Incoming Call', importance: Importance.max, priority: Priority.max, // 将铃声文件放入android/app/src/main/res/raw目录下 sound: const RawResourceAndroidNotificationSound('ringtone'), playSound: true, enableVibration: true, vibrationPattern: const [500, 500, 500], color: UiColor.primary, actions: <AndroidNotificationAction>[ AndroidNotificationAction( 'accept_call', 'Accept', showsUserInterface: true, ), AndroidNotificationAction( 'reject_call', 'Reject', showsUserInterface: true, ), ], )
2. 确保后台通知操作可触发
- 在AndroidManifest.xml中给CallView配置
singleTop启动模式,避免重复启动Activity:
<activity android:name=".views.screens.matches.CallView" android:launchMode="singleTop"> </activity>
- 给
onSelectNotification添加@pragma('vm:entry-point')注解,保证后台点击通知能触发回调:
@pragma('vm:entry-point') void onSelectNotification(NotificationResponse notificationResponse) async { // 原有逻辑保持不变 }
3. 提升后台进程存活能力
- 在AndroidManifest.xml中申请前台服务权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
- 收到来电通知时启动前台服务,避免进程被系统杀死:
// 在showNotification函数中添加(仅Android) if (Platform.isAndroid && message.data['type'] == 'call') { await FlutterBackgroundService().startForegroundService(); }
二、实时追踪(Geolocator + Flutter Background Service)中断修复
1. 优化Geolocator后台定位配置
- 启用后台定位权限,AndroidManifest.xml添加:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
- iOS在Info.plist中添加后台定位相关配置:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>需要后台定位权限以进行实时追踪</string> <key>UIBackgroundModes</key> <array> <string>location</string> </array>
- 配置高精度、高频率的定位参数,同时启用前台通知:
final locationSettings = LocationSettings( accuracy: LocationAccuracy.high, distanceFilter: 10, // 每移动10米更新一次位置 androidSettings: AndroidSettings( intervalDuration: const Duration(seconds: 5), foregroundNotificationConfig: const ForegroundNotificationConfig( notificationText: '实时追踪进行中', notificationTitle: '追踪服务', enableWakeLock: true, // 保持设备唤醒 ), ), ); // 启动位置监听 Geolocator.getPositionStream(locationSettings: locationSettings).listen((position) { // 处理位置更新逻辑(如上传到服务器) });
2. 增强后台服务稳定性
- 配置Flutter Background Service为前台模式,确保进程不被回收:
await FlutterBackgroundService().configure( androidConfiguration: AndroidConfiguration( onStart: onStart, autoStart: true, isForegroundMode: true, notificationChannelId: 'tracking_channel', initialNotificationTitle: '实时追踪', initialNotificationContent: '正在后台运行', foregroundServiceNotificationId: 100, ), iosConfiguration: IosConfiguration( autoStart: true, onForeground: onStart, onBackground: onIosBackground, ), );
- 后台任务逻辑轻量化,避免耗时操作,复杂计算使用Isolate:
@pragma('vm:entry-point') void onStart(ServiceInstance service) async { WidgetsFlutterBinding.ensureInitialized(); // 启动位置监听(同上配置) final locationSettings = LocationSettings(...); Geolocator.getPositionStream(locationSettings: locationSettings).listen((position) { // 仅做位置数据转发,复杂逻辑放入Isolate处理 Isolate.run(() => uploadPositionToServer(position)); }); }
3. 适配国内厂商系统限制
- 引导用户手动开启以下权限(小米、华为、OPPO等厂商默认限制后台进程):
- 自启动权限
- 后台活动权限
- 无限制数据访问权限
内容的提问来源于stack exchange,提问作者Bibin Jose
相关产品推荐
相关产品推荐

