繁体   English   中英

如何使用 Flutter 在后台跟踪位置?

[英]How to track location in background with Flutter?

我一直在 Flutter 开发应用程序的团队工作。我们需要使用 GPS 跟踪行进的距离,但挑战是Flutter 不再允许前景和背景位置跟踪(即使具有粗略的准确度)。

根据对最新谷歌指南的审查,谷歌似乎应该允许我们的应用程序在后台跟踪设备,但事实并非如此。 事实上,打开前台和后台定位服务似乎在一两个月前就开始奏效了。 我们已经尝试了locationgeolocation包,但无济于事。 当应用程序处于后台时,它们中的任何一个都会立即停止跟踪,当应用程序返回前台时,我们的位置会发生很大的跳跃。

这是我们尝试过的

AndroidManifest.xml
...
<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 原生仍然不支持后台本地化。

我见过一些特定于 android 的表单,但没有什么是有效的。

但积极寻找,我发现了这个库:

https://pub.dev/packages/flutter_background_geolocation

这是一个付费库,用于生产(用于 android 密钥。iOS 是免费的)。 而且效果很好。

尽管有成本(这是独一无二的,而且是终生的),但成本效益非常好。

强烈推荐。

注意:他们的文档和支持非常棒。

目前,我正在使用 background_fetch 因为每个人都买不起flutter_background_geolocation定价顺便说一句这个插件也来自同一家公司

background_fetch: ^0.7.2 

到目前为止,它在 Android 中运行良好会很好,但在 ios 中,它需要一些时间作为 Apple 的后台进程算法,一旦它被使用,那么它在 Apple 中也会很好。

这是链接-: 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');

位置插件完美运行并且可以免费使用。 可能有几个原因导致它对您不起作用,就像其他一些外部应用程序在后台杀死您的应用程序一样,或者只是您的设备默认操作系统可能会在后台一段时间后停止应用程序。

Stateful WidgetinitState中调用服务启用代码。

您可以按以下方式收听背景更改:

location.onLocationChanged.listen((LocationData currentLocation) {
  // do whatever you want with new location
});

为此,您需要这个flutter_background_service package。

这个 package 将帮助您在单独的隔离区中运行定位服务。

尝试使用 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内运行您的代码。 isolate 中的代码会运行(即使应用程序已从最近清除),直到您停止后台服务。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM