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

Flutter应用后台实时定位需求:寻求免费解决方案

免费实现Flutter后台实时定位追踪方案

针对你需要的30秒定时推送位置、后台持续运行的需求,结合你之前尝试插件失败的情况,这里提供一套基于geolocator+平台原生后台任务的免费解决方案,覆盖Android和iOS平台:

核心依赖选型

用稳定免费的geolocator获取位置数据,搭配workmanager(Android后台任务调度)和background_fetch(iOS后台唤醒),实现后台定时触发定位推送。

步骤1:添加依赖

在pubspec.yaml中引入:

dependencies:
  geolocator: ^10.1.0
  workmanager: ^0.5.1
  background_fetch: ^1.11.0

执行flutter pub get完成安装。

步骤2:Android平台配置

  1. 权限声明(修改AndroidManifest.xml):
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
  1. 注册WorkManager服务(在<application>标签内添加):
<receiver
    android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver"
    android:exported="false" />
<receiver
    android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
</receiver>
  1. 初始化WorkManager(修改MainActivity.kt):
import be.tramckrijte.workmanager.WorkmanagerPlugin

class MainActivity : FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        WorkmanagerPlugin.registerWith(flutterEngine.dartExecutor.binaryMessenger)
    }
}

步骤3:iOS平台配置

  1. 权限描述(修改Info.plist):
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要获取您的位置以追踪团队成员位置</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>后台需要持续获取位置以追踪团队成员位置</string>
<key>UIBackgroundModes</key>
<array>
    <string>location</string>
    <string>fetch</string>
</array>
  1. 开启后台能力:打开Xcode,选中项目→Signing & Capabilities→添加Background Modes,勾选Location updates和Background fetch。

步骤4:Dart代码实现

  1. 申请定位权限:
import 'package:geolocator/geolocator.dart';
import 'package:workmanager/workmanager.dart';
import 'package:background_fetch/background_fetch.dart';

Future<void> requestLocationPermissions() async {
  final serviceEnabled = await Geolocator.isLocationServiceEnabled();
  if (!serviceEnabled) {
    // 提示用户开启系统定位服务
    return;
  }

  var permission = await Geolocator.checkPermission();
  if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
    if (permission == LocationPermission.denied) return;
  }

  if (permission == LocationPermission.deniedForever) {
    // 引导用户去系统设置开启权限
    await Geolocator.openAppSettings();
  }
}
  1. 配置后台任务:
// Android 后台任务初始化
void initWorkManager() {
  Workmanager().initialize(callbackDispatcher, isInDebugMode: false);
  // 注册30秒周期任务(注意:部分国产ROM会强制延长间隔,需引导用户加白名单)
  Workmanager().registerPeriodicTask(
    "location-track-task",
    "track-location",
    frequency: const Duration(seconds: 30),
    initialDelay: const Duration(seconds: 0),
    constraints: const Constraints(networkType: NetworkType.connected),
  );
}

// iOS 后台唤醒初始化
void initBackgroundFetch() {
  BackgroundFetch.configure(
    const BackgroundFetchConfig(
      minimumFetchInterval: 1, // iOS最低允许1分钟,系统可能自动调整为15分钟
      stopOnTerminate: false,
      startOnBoot: true,
      enableHeadless: true,
    ),
    (taskId) async {
      await fetchAndSendLocation();
      BackgroundFetch.finish(taskId);
    },
    (taskId) => BackgroundFetch.finish(taskId),
  );
}

// Android 任务回调
void callbackDispatcher() {
  Workmanager().executeTask((task, _) async {
    if (task == "track-location") await fetchAndSendLocation();
    return Future.value(true);
  });
}

// 获取并推送位置到后端
Future<void> fetchAndSendLocation() async {
  try {
    final position = await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.best,
    );
    // 替换为你的后端API请求
    // await http.post(
    //   Uri.parse("https://your-backend.com/location"),
    //   body: {"lat": position.latitude.toString(), "lng": position.longitude.toString(), "memberId": "xxx"}
    // );
  } catch (e) {
    // 记录错误日志
  }
}
  1. 全局初始化:
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await requestLocationPermissions();
  initWorkManager();
  initBackgroundFetch();
  runApp(const YourTeamApp());
}

关键注意事项

  • Android:小米、华为等国产ROM会限制后台任务频率,必须引导用户将应用加入后台白名单或省电例外,否则30秒间隔可能被系统强制改为15分钟甚至更久。
  • iOS:系统对后台任务管控严格,minimumFetchInterval设为1分钟但实际触发间隔可能是15分钟左右,若要更精准,可考虑监听位置显著变化,但无法严格保证30秒一次,需根据业务场景折中。
  • 耗电优化:根据需求调整定位精度,团队追踪用LocationAccuracy.best即可,过高精度会增加耗电。

内容的提问来源于stack exchange,提问作者Prashanth Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 22:35:08