You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter iOS端Debug模式后台定位正常但Release/TestFlight环境下失效的问题求助

Flutter iOS端Debug模式后台定位正常但Release/TestFlight环境下失效的问题求助

大家好,我最近折腾Flutter后台定位的时候遇到了一个巨头疼的问题:用flutter_background_service搭配geolocator实现后台位置更新,Debug模式下不管是APP最小化还是锁屏,定位更新都稳稳的,完全没毛病。但一旦打Release包或者通过TestFlight安装到设备上,后台定位直接就停摆了,再也收不到任何位置更新。

我已经在Xcode的info.plist里配置了一堆权限和后台模式,但还是没解决问题,想请各位大佬帮忙看看哪里可能出问题了?

已配置的Xcode info.plist内容

<key>UIBackgroundModes</key>
<array>
  <string>fetch</string>
  <string>location</string>
  <string>remote-notification</string>
  <string>processing</string>
</array>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Your location is needed even when the app is in the background to track trips.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Your location is needed even when the app is in the background to track trips.</string>
<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dict>
  <key>LocationTracking</key>
  <string>This app needs precise location for school bus tracking and safety monitoring purposes.</string>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location is needed to track trips while the app is open.</string>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
  <string>dev.flutter.background.refresh</string>
</array>

后台服务相关代码

后台服务控制器类

class BackgroundServiceController extends ChangeNotifier {
  static final BackgroundServiceController _instance = BackgroundServiceController._internal();
  factory BackgroundServiceController() => _instance;
  BackgroundServiceController._internal();

  final FlutterBackgroundService _service = FlutterBackgroundService();

  Future<void> initializeService({
    required int? disInterval,
    required int? timeInterval,
  }) async {
    SessionController().setDistanceAndTimeInterval(
      disInterval: disInterval.toString(),
      timeInterval: timeInterval.toString(),
    );

    final isRunning = await _service.isRunning();
    if (isRunning) {
      await Future.delayed(const Duration(seconds: 1));
      _service.invoke('setData');
      return;
    }

    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'my_foreground',
      'MY FOREGROUND SERVICE',
      description: 'This channel is used for important notifications.',
      importance: Importance.low,
    );

    final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

    if (Platform.isIOS || Platform.isAndroid) {
      await flutterLocalNotificationsPlugin.initialize(
        const InitializationSettings(
          iOS: DarwinInitializationSettings(),
          android: AndroidInitializationSettings('logo'),
        ),
      );
    }

    await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);

    await _service.configure(
      androidConfiguration: AndroidConfiguration(
        onStart: onStart,
        autoStart: true,
        isForegroundMode: true,
        autoStartOnBoot: true,
        notificationChannelId: 'my_foreground',
        initialNotificationTitle: 'Location Service',
        initialNotificationContent: 'Initializing...',
        foregroundServiceNotificationId: 888,
        foregroundServiceTypes: [AndroidForegroundType.location],
      ),
      iosConfiguration: IosConfiguration(
        autoStart: true,
        onForeground: onStart,
        onBackground: onIosBackground,
      ),
    );

    try {
      await _service.startService();
    } catch (e) {}

    while (!(await _service.isRunning())) {
      await Future.delayed(const Duration(milliseconds: 200));
    }

    await Future.delayed(const Duration(seconds: 3));
    _service.invoke('setData');
  }

  Future<void> stopService() async {
    final isRunning = await _service.isRunning();
    if (isRunning) {
      _service.invoke("stopService");
    }
  }

  Future<bool> isServiceRunning() async {
    return await _service.isRunning();
  }
}

后台服务入口函数

@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
  // DartPluginRegistrant.ensureInitialized();
  WidgetsFlutterBinding.ensureInitialized();
  await AppConstants.init();
  await SessionController().init();

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

  final disInterval = SessionController().disInterval ?? 20;
  final timeInterval = SessionController().timeInterval ?? 10;

  StreamSubscription<Position>? positionStream;
  final homeViewModel = HomeViewModel();

  void startLocationTracking() async {
    if (positionStream != null) {
      return;
    }

    DateTime? lastSentTime;
    positionStream = Geolocator.getPositionStream(
      locationSettings: const LocationSettings(
        distanceFilter: 0,
        accuracy: LocationAccuracy.bestForNavigation,
      ),
    ).listen((position) async {
      final now = DateTime.now();
      if (lastSentTime == null || now.difference(lastSentTime!).inSeconds >= (timeInterval)) {
        lastSentTime = now;
        try {
          await homeViewModel.pushLiveLocation(position: position);
        } catch (e) {}
      }
    });
  }

  // 补全停止服务的监听逻辑
  service.on('stopService').listen((event) {
    positionStream?.cancel();
    service.stopSelf();
  });

  // 启动定位追踪
  startLocationTracking();
}

我已经确认用户授权了「始终允许」的定位权限,Debug环境下所有逻辑都正常,唯独Release/TestFlight环境下后台定位失效。有没有大佬遇到过类似问题,或者能指出我哪里配置或代码有疏漏?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:18:10