我一直在一个团队中使用 Flutter 开发应用程序。我们需要使用 GPS 跟踪行驶的距离,但挑战是 Flutter 不再允许前景和后台位置跟踪(即使具有粗略的准确度)。
根据对最新 Google 指南的审查,Google 似乎应该允许我们的应用程序在后台跟踪设备,但事实并非如此。事实上,打开前台和后台定位服务似乎在一两个月前就起作用了。我们已经尝试了
location
和geolocation
套餐,但没有成功。当应用程序处于后台时,它们中的任何一个都会立即停止跟踪,并且当应用程序返回到前台时,我们的位置会发生很大的跳跃。
...
<uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
...
...
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
return Future.error('Location permissions are denied');
}
}
//Permission returns denied Location
//this is due to the background permission in the android manifest
//turn off background permission and the permission is allowed
if (permission == LocationPermission.deniedForever)
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
...
_serviceEnabled = await location.serviceEnabled();
if (!_serviceEnabled) {
_serviceEnabled = await location.requestService();
if (!_serviceEnabled) {
print('Service could not be enabled');
return false;
}
// This code throws and exception even if I respond to the
// Google prompts and I select allow location service and all the time access
try {
await location.enableBackgroundMode(enable: true);
} catch(error) {
print("Can't set background mode");
}
任何有关如何实现这一目标的指导将不胜感激。
尝试使用 flutter_background_service
flutter_background_service: ^2.4.6
所需设置:
await service.configure(
androidConfiguration: AndroidConfiguration(
onStart: onStart,
isForegroundMode: true,
notificationChannelId: 'my_foreground',
initialNotificationTitle: 'AWESOME SERVICE',
initialNotificationContent: 'Initializing',
foregroundServiceNotificationId: 888,
),);
在此后台服务中使用geoloactor,
@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
// use geolocator to get location here
}
这将发出通知并在单独隔离的 onStart 中运行您的代码。隔离中的代码会运行(即使应用程序已从最近的状态中清除),直到您停止后台服务。
Flutter 本身仍然不支持后台本地化。
我见过一些android特有的形式,但没有什么效果。
但是积极寻找,我发现了这个库:
https://pub.dev/packages/flutter_background_geolocation
这是一个付费库,用于生产(适用于 Android 密钥。iOS 是免费的)。而且效果非常好。
尽管有成本(这是独特的且终生的),但成本效益非常好。
强烈推荐。
注意:他们的文档和支持非常棒。
location插件运行完美并且可以免费使用。 可能有多种原因导致它对您不起作用,例如某些其他外部应用程序在后台杀死您的应用程序,或者只是您的设备默认操作系统可能会在后台运行一段时间后停止应用程序。
在您的
initState
的Stateful Widget
中调用服务启用代码。
您可以聆听背景变化:
location.onLocationChanged.listen((LocationData currentLocation) {
// do whatever you want with new location
});
您需要这个 flutter_background_service 包。
这个包将帮助您在单独的隔离中运行位置服务。
目前,我正在使用background_fetch,因为每个人都买不起flutter_background_geolocation定价顺便说一句,这个插件也来自同一家公司
background_fetch: ^0.7.2
到目前为止,它在 Android 中工作得很好,但在 ios 中,需要一些时间,因为苹果的后台进程算法一旦使用,那么在苹果中也会很好。
这是链接-: https://pub.dev/packages/background_fetch
设置
int status = await BackgroundFetch.configure(
BackgroundFetchConfig(
minimumFetchInterval: 30,
stopOnTerminate: true,
enableHeadless: false,
startOnBoot: false,
requiresBatteryNotLow: false,
requiresCharging: false,
requiresStorageNotLow: false,
requiresDeviceIdle: false,
requiredNetworkType: NetworkType.NONE),
(taskId){
// This is the fetch-event callback.
},
(taskId){
// This task has exceeded its allowed running time.
// You must stop what you're doing and immediately finish(taskId)
});
print('[BackgroundFetch] configure success: $status');
这里有一个解决方法
使用 flutter_foreground_task 插件让你的任务在后台运行。这里的背景是指当你的应用程序没有从最近的任务中关闭时
使用 fl_location 插件在变化时持续获取用户位置
确保遵循上述两个软件包的自述文件中提到的先决条件,以使您的应用程序在后台完全正常运行
从 flutter_foreground_task 插件实现接口时,请确保监听
FlLocation.getLocationStream()
的
onStart()
函数内的
TaskHandler
函数
监听
FlLocation.getLocationStream()
时,使用sendPort.send()
功能将位置数据发送到主隔离区
记住监听主隔离上的端口(应用程序运行的位置)
现在,当您收到主隔离上的数据时,您可以做任何您想做的事情...将其发送到某个网络套接字或其他东西...
它适用于我的 iOS 17.1.1 和 Android 13。请告诉我它是否适合您!