简体   繁体   English

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

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

I have been working on a team developing an app in Flutter. We need to track the distance travelled using the GPS but the challenge is that Flutter no longer allows both foreground and background location tracking (even with a coarse level of accuracy).我一直在 Flutter 开发应用程序的团队工作。我们需要使用 GPS 跟踪行进的距离,但挑战是Flutter 不再允许前景和背景位置跟踪(即使具有粗略的准确度)。

Based on a review of the latest Google guidelines, it seems like Google should allow our app to track the device when it's in the background, but it does not.根据对最新谷歌指南的审查,谷歌似乎应该允许我们的应用程序在后台跟踪设备,但事实并非如此。 In fact, turning on foreground and background location services seemed to be working a month or two back.事实上,打开前台和后台定位服务似乎在一两个月前就开始奏效了。 We have tried both the location and geolocation packages, to no avail.我们已经尝试了locationgeolocation包,但无济于事。 Either of them immediately stops tracking when the app is in the background and we get one big jump in location when the app is returned to the foreground.当应用程序处于后台时,它们中的任何一个都会立即停止跟踪,当应用程序返回前台时,我们的位置会发生很大的跳跃。

Here's what we've tried这是我们尝试过的

AndroidManifest.xml AndroidManifest.xml
...
<uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
...

App Code Using Geolocation使用地理定位的应用程序代码
...
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.');
}
...
App Code Using Location使用位置的应用程序代码
_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");
}

Any guidance for how to achieve this would be much appreciated.任何关于如何实现这一目标的指导将不胜感激。

Natively, Flutter still doesn't support background localization. Flutter 原生仍然不支持后台本地化。

I've seen some android-specific forms, but nothing was effective.我见过一些特定于 android 的表单,但没有什么是有效的。

But actively looking, I found this lib:但积极寻找,我发现了这个库:

https://pub.dev/packages/flutter_background_geolocation https://pub.dev/packages/flutter_background_geolocation

It's a paid lib, to be used in production (for android keys. iOS is free).这是一个付费库,用于生产(用于 android 密钥。iOS 是免费的)。 And it works perfectly.而且效果很好。

Despite having a cost (which is unique and for life) the cost benefit is very good.尽管有成本(这是独一无二的,而且是终生的),但成本效益非常好。

Highly recommend.强烈推荐。

Note: Their documentation and support is wonderful.注意:他们的文档和支持非常棒。

Currently, I am using the background_fetch because everyone can't afford flutter_background_geolocation pricing BTW this plugin is also from the same company目前,我正在使用 background_fetch 因为每个人都买不起flutter_background_geolocation定价顺便说一句这个插件也来自同一家公司

background_fetch: ^0.7.2 

So far it's working fine in Android will work nicely but in ios, it will take some time reason being Apple's background process algorithm once it will get used then It will be fine in apple as well.到目前为止,它在 Android 中运行良好会很好,但在 ios 中,它需要一些时间作为 Apple 的后台进程算法,一旦它被使用,那么它在 Apple 中也会很好。

Here is the link-: https://pub.dev/packages/background_fetch这是链接-: https ://pub.dev/packages/background_fetch

Setup设置

   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');

The location plugin works perfectly and is free to use.位置插件完美运行并且可以免费使用。 There could be several reasons that it did not work for you like some other external application killing your app in background or just your devices default OS could be stopping the application after a while in background.可能有几个原因导致它对您不起作用,就像其他一些外部应用程序在后台杀死您的应用程序一样,或者只是您的设备默认操作系统可能会在后台一段时间后停止应用程序。

Call the service enabling code in the initState of your Stateful Widget .Stateful WidgetinitState中调用服务启用代码。

You can listen to the background changes as:您可以按以下方式收听背景更改:

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

You need this flutter_background_service package for this.为此,您需要这个flutter_background_service package。

This package will help you to run the location service in a separate isolate.这个 package 将帮助您在单独的隔离区中运行定位服务。

Try using flutter_background_service尝试使用 flutter_background_service

flutter_background_service: ^2.4.6

Required setup:所需设置:

await service.configure(
androidConfiguration: AndroidConfiguration(
  onStart: onStart,
  isForegroundMode: true,
  notificationChannelId: 'my_foreground',
  initialNotificationTitle: 'AWESOME SERVICE',
  initialNotificationContent: 'Initializing',
  foregroundServiceNotificationId: 888,
),);

Use geoloactor within this background service,在此后台服务中使用geoloactor

@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
 
  // use geolocator to get location here

}

This will shoot a notification and runs your code inside onStart on a separate isolate.这将发出通知并在单独的隔离区的onStart内运行您的代码。 The code inside isolate runs (even when the app is cleared from the recent) till you stop the background service. isolate 中的代码会运行(即使应用程序已从最近清除),直到您停止后台服务。

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

相关问题 如何使用 android 应用程序在后台跟踪位置? - How to track location in the background using an android app? Flutter 后台位置访问 - Flutter background location access 跟踪用户位置的前台或后台服务? - Foreground or Background service to track user's location? 如何删除被谷歌拒绝的 FLUTTER APP 中的 ACCES 背景位置 - How to Remove ACCES BACKGROUND LOCATION IN FLUTTER APP REJECTED BYY GOOGLE 应用程序被杀死时是否可以跟踪用户的位置(Flutter) - Is it possible to track User's Location when app is killed (Flutter) 在颤动的背景中从android获取位置 - Fetch location from android in background in flutter 跟踪用户在后台的GPS位置,并通知他是否在某个点附近 - Track users GPS location in the background and notify if he is next to a certain point 即使应用程序被终止或在后台,是否有办法跟踪 GPS 本地化? Flutter 应用程序 - Is there a way to track GPS localisation even with the app killed or in background? Flutter app 使用 flutter 定位插件在 Android 中自动添加后台定位权限 - Background location permission auto-added in Android with flutter location plugin 在运动过程中如何跟踪手指的位置? - How to track a finger's location during movement?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM