如何在屏幕关闭时让Flutter应用保持后台运行并共享位置
针对你遇到的屏幕关闭后应用1分钟左右就停止位置共享的问题,核心原因是Android和iOS的后台限制机制,wakelock包并非唯一方案,且你可以通过配置它的唤醒类型实现屏幕关闭但CPU保持运行,另外结合平台特定的后台位置权限和服务才能长期稳定运行:
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.FOREGROUND_SERVICE_LOCATION" />其中
ACCESS_BACKGROUND_LOCATION是Android 10+后台位置更新的必要权限,FOREGROUND_SERVICE_LOCATION用于前台服务声明。启用前台服务
Android 8.0+对后台应用限制严格,只有前台服务能让应用在后台持续运行。你可以用geolocator自带的前台服务支持:await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.best, forceAndroidLocationManager: true, ); await Geolocator.openAppSettings(); await Geolocator.openLocationSettings(); // 启动后台位置更新并绑定前台服务 await Geolocator.getPositionStream( locationSettings: LocationSettings( accuracy: LocationAccuracy.best, distanceFilter: 10, androidSettings: AndroidSettings( foregroundNotificationConfig: ForegroundNotificationConfig( notificationText: "正在共享位置", notificationTitle: "位置共享中", enableWakeLock: true, // 仅保持CPU运行,屏幕可正常关闭 ), ), ), ).listen((Position position) { // 处理位置更新逻辑 });应对Doze模式
设备进入Doze模式后系统会限制后台活动,尽量避免将应用加入白名单(影响省电),而是通过调整位置更新的间隔和距离阈值,减少不必要的唤醒频率。
iOS 端配置
开启后台模式权限
在Xcode中打开项目的Info.plist,完成两项配置:- 开启
Background Modes中的Location updates选项 - 添加权限描述:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>需要持续获取位置以共享你的活动位置</string> <key>NSLocationWhenInUseUsageDescription</key> <string>需要获取位置以共享你的活动位置</string>
- 开启
配置位置管理器
使用geolocator时开启后台位置更新:await Geolocator.requestPermission(); await Geolocator.getPositionStream( locationSettings: LocationSettings( accuracy: LocationAccuracy.best, distanceFilter: 10, iosSettings: IosSettings( allowBackgroundLocationUpdates: true, pauseLocationUpdatesAutomatically: false, // 禁止系统自动暂停更新 ), ), ).listen((Position position) { // 处理位置更新逻辑 });iOS的后台位置更新依赖系统调度,权限配置正确后即使屏幕关闭也能持续获取位置,但需注意频繁更新会增加电量消耗,建议根据需求调整
distanceFilter和accuracy参数。
关于wakelock包的补充用法
你之前使用wakelock包时可能默认启用了全屏唤醒,其实该包支持仅保持CPU运行、允许屏幕关闭的配置:
import 'package:wakelock/wakelock.dart'; // 仅唤醒CPU,屏幕可正常关闭 await Wakelock.enable(enableScreen: false);
这个设置可以配合前台服务或后台位置权限,进一步降低应用被系统查杀的概率。
通用注意事项
- 后台持续运行必然增加电量消耗,建议根据实际需求调整位置更新的频率和精度,平衡功能与省电效果。
- Android端需引导用户手动授予后台位置权限,否则无法在后台持续获取位置。
- iOS端若对位置精度要求不高,可使用显著位置变化服务(
significantLocationChangeUpdates),大幅降低电量消耗。
内容的提问来源于stack exchange,提问作者Christophe LYONNAZ

