Flutter iOS应用关闭后后台定位更新失效问题求助
Flutter iOS后台定位失效问题
我开发的Flutter应用使用flutter_background_service包实现后台定位任务,onStart函数作为后台服务入口,负责定期采集并更新设备位置。该功能在Android端表现正常,即使关闭应用也能持续运行,但在iOS端仅能在应用处于运行或暂停状态时生效。
我已完成以下配置和代码编写:
已完成的配置
Info.plist配置
<key>BGTaskSchedulerPermittedIdentifiers</key> <array> <string>dev.flutter.background.refresh</string> <string>myBackgroundTask</string> </array> <key>UIBackgroundModes</key> <array> <string>location</string> <string>fetch</string> <string>remote-notification</string> </array>
AppDelegate.swift配置
import UIKit import Flutter import flutter_background_service_ios @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { SwiftFlutterBackgroundServicePlugin.taskIdentifier = "dev.flutter.background.refresh" GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }
核心代码实现
后台服务初始化函数
Future<void> initializeBackgroundService() async { final service = FlutterBackgroundService(); await service.configure( androidConfiguration: AndroidConfiguration( onStart: onStart, autoStart: false, autoStartOnBoot: false, isForegroundMode: true, initialNotificationTitle: "Tracking", initialNotificationContent: 'Refreshing', ), iosConfiguration: IosConfiguration( autoStart: false, onForeground: onStart, ), ); }
后台服务入口函数onStart
Timer? timer; @pragma('vm:entry-point') void onStart(ServiceInstance service) async { print("onStart called with $service"); try { DartPluginRegistrant.ensureInitialized(); String __ = ""; String version = ""; String __ = ""; String url = ""; Position? position; if (Platform.isAndroid) { log("device is android"); if (service is AndroidServiceInstance) { log("device is android service instance"); service.on('setAsForeground').listen((event) async { //自定义业务代码 }); } } else if (Platform.isIOS) { service.on('setAsForeground').listen((event) async { //自定义业务代码 }); } if (Platform.isIOS) { final NotificationService notificationService = NotificationService(); await notificationService.initializePlatformNotifications(); } service.on('stopService').listen((event) async { timer?.cancel(); await service.stopSelf(); log("Service stopped"); }); if (Platform.isAndroid) { log("first notification android"); if (service is AndroidServiceInstance && await service.isForegroundService()) { service.setForegroundNotificationInfo( title: "Tracking", content: "Last updated at ${DateFormat.jm().format(DateTime.now())}, ${DateFormat.yMd().format(DateTime.now())}", ); } } else if (Platform.isIOS) { await NotificationService.showNotification( id: 0, title: "Tracking", body: "Last updated at ${DateFormat.jm().format(DateTime.now())}, ${DateFormat.yMd().format(DateTime.now())}", data: "", ); } timer?.cancel(); timer = Timer.periodic(const Duration(seconds: 10), (timer) async { if (Platform.isAndroid) { log("authcode for android $authcode"); if (service is AndroidServiceInstance) { if (await service.isForegroundService()) { Position? position; bool isLocationEnabled = await Geolocator.isLocationServiceEnabled(); bool isPermissionGranted = await Geolocator.checkPermission() == LocationPermission.whileInUse || await Geolocator.checkPermission() == LocationPermission.always; if (isLocationEnabled && isPermissionGranted) { position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.bestForNavigation); if (position.accuracy > 200) { StreamSubscription<Position> positionStream = Geolocator.getPositionStream( locationSettings: AndroidSettings( accuracy: LocationAccuracy.bestForNavigation, distanceFilter: 0, intervalDuration: const Duration(seconds: 1), ), ).listen((Position value) { position = value; }); await Future.delayed(const Duration(seconds: 5)); await positionStream.cancel(); } log("authcode for android before call $authcode"); log("url for android before call $url"); //发送位置的业务逻辑 } else { timer.cancel(); service.stopSelf(); } } } } else if (Platform.isIOS) { Position? position; bool isLocationEnabled = await Geolocator.isLocationServiceEnabled(); bool isPermissionGranted = await Geolocator.checkPermission() == LocationPermission.whileInUse || await Geolocator.checkPermission() == LocationPermission.always; if (isLocationEnabled && isPermissionGranted) { position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.bestForNavigation); if (position.accuracy > 200) { StreamSubscription<Position> positionStream = Geolocator.getPositionStream( locationSettings: AppleSettings( accuracy: LocationAccuracy.bestForNavigation, distanceFilter: 0, timeLimit: const Duration(seconds: 1), activityType: ActivityType.otherNavigation, ), ).listen((Position value) { position = value; }); await Future.delayed(const Duration(seconds: 5)); await positionStream.cancel(); } //发送位置的业务逻辑 } else { timer.cancel(); service.stopSelf(); } } print('FLUTTER BACKGROUND SERVICE: ${DateTime.now()}'); }); } catch (e, stack) { print(e); print('stack: $stack'); } }
内容的提问来源于stack exchange,提问作者Rakibul
相关产品推荐
相关产品推荐

