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平台配置
- 权限声明(修改
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" />
- 注册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>
- 初始化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平台配置
- 权限描述(修改
Info.plist):
<key>NSLocationWhenInUseUsageDescription</key> <string>需要获取您的位置以追踪团队成员位置</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>后台需要持续获取位置以追踪团队成员位置</string> <key>UIBackgroundModes</key> <array> <string>location</string> <string>fetch</string> </array>
- 开启后台能力:打开Xcode,选中项目→Signing & Capabilities→添加Background Modes,勾选Location updates和Background fetch。
步骤4:Dart代码实现
- 申请定位权限:
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(); } }
- 配置后台任务:
// 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) { // 记录错误日志 } }
- 全局初始化:
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
相关产品推荐
相关产品推荐

