Giter VIP home page Giter VIP logo

geofence_service's Introduction

This plugin is a geofence service with activity recognition API. It does not use the Geofence API implemented on the platform. Therefore, battery efficiency cannot be guaranteed. Instead, this plugin can provide more accurate and realtime geo-fencing by navigating your location while your app is alive.

pub package

Features

  • Geofence can have multiple radius.
  • Geofence can see what activity took place when the device entered the radius.
  • GeofenceService can perform geo-fencing in real time and catch errors during operation.
  • GeofenceService can be operated in the background using WillStartForegroundTask widget.

WAIT: This plugin performs geo-fencing based on a circular geofence. If you want to create a polygon geofence, this plugin is recommended.

Getting started

To use this plugin, add geofence_service as a dependency in your pubspec.yaml file. For example:

dependencies:
  geofence_service: ^5.0.0

After adding the geofence_service plugin to the flutter project, we need to specify the platform-specific permissions and services to use for this plugin to work properly.

🐀 Android

Since geo-fencing operates based on location, we need to add the following permission to the AndroidManifest.xml file. Open the AndroidManifest.xml file and specify it between the <manifest> and <application> tags.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

If you want to run the service in the background, add the following permission. If your project supports Android 10, be sure to add the ACCESS_BACKGROUND_LOCATION permission.

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

And specify the service inside the <application> tag as follows.

<service
    android:name="com.pravera.flutter_foreground_task.service.ForegroundService"
    android:foregroundServiceType="location"
    android:stopWithTask="true" />

The biggest feature of this plugin is that it can know user activity while geo-fencing. Please specify the permission usage in <manifest> tag.

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />

🐀 iOS

Like Android platform, geo-fencing is based on location, we need to add the following description. Open the ios/Runner/Info.plist file and specify it inside the <dict> tag.

<key>NSLocationWhenInUseUsageDescription</key>
<string>Used to provide geofence service.</string>

If you want to run the service in the background, add the following description.

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Used to provide geofence services in the background.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Used to provide geofence services in the background.</string>
<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
    <string>location</string>
</array>

To detect changes in user activity, add the following description.

<key>NSMotionUsageDescription</key>
<string>Used to recognize user activity information.</string>

(Optional) To display a notification when your app enters the background, you need to open the ios/Runner/AppDelegate file and set the following:

Objective-C:

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];

  // here
  if (@available(iOS 10.0, *)) {
    [UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;
  }

  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

Swift:

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)

    // here
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    }

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

How to use

  1. Create a GeofenceService instance and set options. GeofenceService.instance.setup() provides the following options:
  • interval: The time interval in milliseconds to check the geofence status. The default is 5000.
  • accuracy: Geo-fencing error range in meters. The default is 100.
  • loiteringDelayMs: Sets the delay between GeofenceStatus.ENTER and GeofenceStatus.DWELL in milliseconds. The default is 300000.
  • statusChangeDelayMs: Sets the status change delay in milliseconds. GeofenceStatus.ENTER and GeofenceStatus.EXIT events may be called frequently when the location is near the boundary of the geofence. Use this option to minimize event calls at this time. If the option value is too large, realtime geo-fencing is not possible, so use it carefully. The default is 10000.
  • useActivityRecognition: Whether to use the activity recognition API. The default is true.
  • allowMockLocations: Whether to allow mock locations. The default is false.
  • printDevLog: Whether to show the developer log. If this value is set to true, logs for geofence service activities (start, stop, etc.) can be viewed. It does not work in release mode. The default is false.
  • geofenceRadiusSortType: Sets the sort type of the geofence radius. The default is GeofenceRadiusSortType.DESC.
// Create a [GeofenceService] instance and set options.
final _geofenceService = GeofenceService.instance.setup(
    interval: 5000,
    accuracy: 100,
    loiteringDelayMs: 60000,
    statusChangeDelayMs: 10000,
    useActivityRecognition: true,
    allowMockLocations: false,
    printDevLog: false,
    geofenceRadiusSortType: GeofenceRadiusSortType.DESC);
  1. Create a Geofence and GeofenceRadius list. Geofence and GeofenceRadius provides the following parameters:
  • id: Identifier for Geofence and GeofenceRadius.
  • data: Custom data for Geofence and GeofenceRadius.
  • latitude: The latitude of geofence center.
  • longitude: The longitude of geofence center.
  • radius: The radius of Geofence.
  • length: The length of the radius in meters. The best result should be set between 100 and 150 meters in radius. If Wi-FI is available, it can be set up to 20~40m.
// Create a [Geofence] list.
final _geofenceList = <Geofence>[
  Geofence(
    id: 'place_1',
    latitude: 35.103422,
    longitude: 129.036023,
    radius: [
      GeofenceRadius(id: 'radius_100m', length: 100),
      GeofenceRadius(id: 'radius_25m', length: 25),
      GeofenceRadius(id: 'radius_250m', length: 250),
      GeofenceRadius(id: 'radius_200m', length: 200),
    ],
  ),
  Geofence(
    id: 'place_2',
    latitude: 35.104971,
    longitude: 129.034851,
    radius: [
      GeofenceRadius(id: 'radius_25m', length: 25),
      GeofenceRadius(id: 'radius_100m', length: 100),
      GeofenceRadius(id: 'radius_200m', length: 200),
    ],
  ),
];
  1. Register the listener and call GeofenceService.instance.start().
// This function is to be called when the geofence status is changed.
Future<void> _onGeofenceStatusChanged(
    Geofence geofence,
    GeofenceRadius geofenceRadius,
    GeofenceStatus geofenceStatus,
    Location location) async {
  print('geofence: ${geofence.toJson()}');
  print('geofenceRadius: ${geofenceRadius.toJson()}');
  print('geofenceStatus: ${geofenceStatus.toString()}');
  _geofenceStreamController.sink.add(geofence);
}

// This function is to be called when the activity has changed.
void _onActivityChanged(Activity prevActivity, Activity currActivity) {
  print('prevActivity: ${prevActivity.toJson()}');
  print('currActivity: ${currActivity.toJson()}');
  _activityStreamController.sink.add(currActivity);
}

// This function is to be called when the location has changed.
void _onLocationChanged(Location location) {
  print('location: ${location.toJson()}');
}

// This function is to be called when a location services status change occurs
// since the service was started.
void _onLocationServicesStatusChanged(bool status) {
  print('isLocationServicesEnabled: $status');
}

// This function is used to handle errors that occur in the service.
void _onError(error) {
  final errorCode = getErrorCodesFromError(error);
  if (errorCode == null) {
    print('Undefined error: $error');
    return;
  }
  
  print('ErrorCode: $errorCode');
}

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_) {
    _geofenceService.addGeofenceStatusChangeListener(_onGeofenceStatusChanged);
    _geofenceService.addLocationChangeListener(_onLocationChanged);
    _geofenceService.addLocationServicesStatusChangeListener(_onLocationServicesStatusChanged);
    _geofenceService.addActivityChangeListener(_onActivityChanged);
    _geofenceService.addStreamErrorListener(_onError);
    _geofenceService.start(_geofenceList).catchError(_onError);
  });
}
  1. Add WillStartForegroundTask widget for background execution on Android platform. WillStartForegroundTask provides the following options:
  • onWillStart: Called to ask if you want to start the foreground task.
  • notificationOptions: Optional values for notification detail settings.
  • notificationTitle: The title that will be displayed in the notification.
  • notificationText: The text that will be displayed in the notification.
  • child: A child widget that contains the Scaffold widget.
@override
Widget build(BuildContext context) {
  return MaterialApp(
    // A widget used when you want to start a foreground task when trying to minimize or close the app.
    // Declare on top of the [Scaffold] widget.
    home: WillStartForegroundTask(
      onWillStart: () async {
        // You can add a foreground task start condition.
        return _geofenceService.isRunningService;
      },
      androidNotificationOptions: AndroidNotificationOptions(
        channelId: 'geofence_service_notification_channel',
        channelName: 'Geofence Service Notification',
        channelDescription: 'This notification appears when the geofence service is running in the background.',
        channelImportance: NotificationChannelImportance.LOW,
        priority: NotificationPriority.LOW,
        isSticky: false,
      ),
      iosNotificationOptions: const IOSNotificationOptions(),
      foregroundTaskOptions: const ForegroundTaskOptions(),
      notificationTitle: 'Geofence Service is running',
      notificationText: 'Tap to return to the app',
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Geofence Service'),
          centerTitle: true,
        ),
        body: _buildContentView(),
      ),
    ),
  );
}
  1. To add or remove Geofence while the service is running, use the following function:
_geofenceService.addGeofence(Object);
_geofenceService.addGeofenceList(List);
_geofenceService.removeGeofence(Object);
_geofenceService.removeGeofenceList(List);
_geofenceService.removeGeofenceById(String);
_geofenceService.clearGeofenceList();
  1. If you want to pause or resume the service, use the function below.
_geofenceService.pause();
_geofenceService.resume();
  1. When you are finished using the service, unregister the listener and call GeofenceService.instance.stop().
_geofenceService.removeGeofenceStatusChangeListener(_onGeofenceStatusChanged);
_geofenceService.removeLocationChangeListener(_onLocationChanged);
_geofenceService.removeLocationServicesStatusChangeListener(_onLocationServicesStatusChanged);
_geofenceService.removeActivityChangeListener(_onActivityChanged);
_geofenceService.removeStreamErrorListener(_onError);
_geofenceService.clearAllListeners();
_geofenceService.stop();

Note: When calling the stop function, the listener is not removed, but the added geofence is cleared.

Models

πŸ” Geofence

A model representing a geofence.

Property Description
id Identifier for Geofence.
data Custom data for Geofence.
latitude The latitude of geofence center.
longitude The longitude of geofence center.
radius The radius of Geofence.
status The status of Geofence.
timestamp The timestamp of Geofence.
remainingDistance The remaining distance to the destination.

πŸ” GeofenceRadius

A model representing the radius of Geofence.

Property Description
id Identifier for GeofenceRadius.
data Custom data for GeofenceRadius.
length The length of the radius in meters.
status The status of GeofenceRadius.
activity The user activity when geofence status changes.
speed The passing speed when geofence status changes.
timestamp The timestamp when geofence status changes.
remainingDistance The remaining distance to the radius.

πŸ” GeofenceStatus

Defines the type of the geofence status.

Value Description
ENTER Occurs when entering the geofence radius.
EXIT Occurs when exiting the geofence radius.
DWELL Occurs when the loitering delay elapses after entering the geofence area.

πŸ” Activity

A model representing the user's activity.

Property Description
type The type of activity recognized.
confidence The confidence of activity recognized.

πŸ” ActivityType

Defines the type of activity.

Value Description
IN_VEHICLE The device is in a vehicle, such as a car.
ON_BICYCLE The device is on a bicycle.
RUNNING The device is on a user who is running. This is a sub-activity of ON_FOOT.
STILL The device is still (not moving).
WALKING The device is on a user who is walking. This is a sub-activity of ON_FOOT.
UNKNOWN Unable to detect the current activity.

πŸ” ActivityConfidence

Defines the confidence of activity.

Value Description
HIGH High accuracy: 75~100
MEDIUM Medium accuracy: 50~75
LOW Low accuracy: 0~50

πŸ” GeofenceRadiusSortType

Defines the sort type of the geofence radius. If you have set multiple radius for one geofence, multiple radius can come in at the same time. At this time, you can control the order in which the radius comes in by referring to the radius meters.

Value Description
ASC Sort the meters in ascending order.
DESC Sort the meters in descending order.

πŸ” ErrorCodes

Error codes that may occur in the service.

Value Description
ALREADY_STARTED Occurs when the service has already been started but the start function is called.
LOCATION_SERVICES_DISABLED Occurs when location services are disabled. When this error occurs, you should notify the user and request activation.
LOCATION_PERMISSION_DENIED Occurs when location permission is denied.
LOCATION_PERMISSION_PERMANENTLY_DENIED Occurs when location permission is permanently denied. In this case, the user must manually allow the permission.
ACTIVITY_RECOGNITION_PERMISSION_DENIED Occurs when activity recognition permission is denied.
ACTIVITY_RECOGNITION_PERMISSION_PERMANENTLY_DENIED Occurs when activity recognition permission is permanently denied. In this case, the user must manually allow the permission.

Support

If you find any bugs or issues while using the plugin, please register an issues on GitHub. You can also contact us at [email protected].

geofence_service's People

Contributors

dev-hwang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

geofence_service's Issues

doesn't work in background

Hey,
I use this package to send a notification when the user arrives someplace but when an app is open application wok correctly but when the app in the background or closed nothing happened.
Is there any way to send a notification when the app is in the background or closed?

Issue with shared_preferences package

Hi
Recently I added this package to our project in order to use the geo-fencing feature, but it seems that its dependencies use shared_preferences_ios which is incompatible with the latest shared_preferences package as "shared_preferences: ^2.0.18"
it causes an error as follows:

[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)

Could you please tell me what's going on?

Unable to kill app from Paused state in Android

Firstly, thank you for your (continued) work on this and other libraries.

When the Android app is running in the foreground (in a Paused lifecycle state), and when I kill the app by swiping it up from the App Overview (the third button in a 3-button navigation layout), the emulator does not exit and I get the following recurring message:

Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. 
Could not send. Channel: plugins.pravera.com/fl_location/updates. Response ID: 12

Note this behaviour doesn't happen if you kill the app by selecting the App Overview button when the app is Active - only when the app is already in the foreground and paused (I have a habit of closing the apps on my phone periodically, and I noticed the battery usage of this app spiked following killing of the app)

I have tried setting android:stopWithTask="false" and calling dispose manually, and many different attempts to cancel the stream listener manually - however it seems killing the app running in foreground kills the Flutter engine before cancelling the location calculation stream and I don't know how to reorder this sequence. The Android Studio Logcat error that I also tried to unsuccessfully troubleshoot is below:

2021-12-05 01:42:02.642 533-3929/system_process W/InputManager-JNI: Input channel object '32225f9 com.example.test_app2/com.example.test_app2.MainActivity (client)' was disposed without first being removed with the input manager!
2021-12-05 01:42:02.644 533-562/system_process W/UsageStatsService: Unexpected activity event reported! (com.example.test_app2/com.example.test_app2.MainActivity event : 23 instanceId : 209389694)

I created a repo with the current setup embedded in a basic Flutter app here: https://github.com/stantonius/geolocation_debug_app

Any ideas about why this might be occurring?

The flutter doctor is below

[βœ“] Flutter (Channel beta, 2.8.0-3.3.pre, on macOS 12.0.1 21A559 darwin-arm, locale en-GB)
    β€’ Flutter version 2.8.0-3.3.pre at /Development/flutter
    β€’ Upstream repository https://github.com/flutter/flutter.git
    β€’ Framework revision 262b70ece1 (3 days ago), 2021-12-01 13:00:48 -0800
    β€’ Engine revision 06a7363b0c
    β€’ Dart version 2.15.0 (build 2.15.0-268.18.beta)

[βœ“] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    β€’ Android SDK at /Library/Android/sdk
    β€’ Platform android-31, build-tools 31.0.0
    β€’ ANDROID_SDK_ROOT = /Library/Android/sdk
    β€’ Java binary at: /Downloads/Android Studio.app/Contents/jre/Contents/Home/bin/java
    β€’ Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
    β€’ All Android licenses accepted.

[βœ—] Xcode - develop for iOS and macOS
    βœ— Xcode installation is incomplete; a full installation is necessary for iOS development.
      Download at: https://developer.apple.com/xcode/download/
      Or install Xcode via the App Store.
      Once installed, run:
        sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
        sudo xcodebuild -runFirstLaunch
    βœ— CocoaPods not installed.
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.

[βœ“] Chrome - develop for the web
    β€’ Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[βœ“] Android Studio (version 2020.3)
    β€’ Android Studio at 
    β€’ Flutter plugin can be installed from:
      πŸ”¨ https://plugins.jetbrains.com/plugin/9212-flutter
    β€’ Dart plugin can be installed from:
      πŸ”¨ https://plugins.jetbrains.com/plugin/6351-dart
    β€’ Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)

[βœ“] IntelliJ IDEA Community Edition (version 2021.2.3)
    β€’ IntelliJ at /Applications/IntelliJ IDEA CE.app
    β€’ Flutter plugin version 62.0.3
    β€’ Dart plugin version 212.5632

[βœ“] VS Code (version 1.62.3)
    β€’ VS Code at /Applications/Visual Studio Code.app/Contents
    β€’ Flutter extension version 3.29.0

[βœ“] Connected device (2 available)
    β€’ sdk gphone64 arm64 (mobile) β€’ emulator-5554 β€’ android-arm64  β€’ Android 12 (API 31) (emulator)
    β€’ Chrome (web)                β€’ chrome        β€’ web-javascript β€’ Google Chrome 96.0.4664.55

How can I trigger a notfication for the app to open a view

Hi There, thank you for a great plugin. I have implemented it and am getting an output in the console for each of my GeoFences, which is excellent.

I am a bit of a newb, so apologies for the question, but if you could help, it may assist others.

I need to do two things:

  1. When the app is in the background but in an active state, and a user enters 1 of the GeoFence locations, I need to notify the user to ask them to open the app and, when tapped, launch a view which receives an integer.
  2. Similar to 1, when the app is in view (the user is using it), there is a snack bar notifying the user that a location has been reached and allowing them to tap to open the same view.

Could you help me out with this? I am so close to getting this working, and your plugin has helped with a very complex element thus far.

Thank you in advance

Notification when DWELL

How can it be implemented that the notification is only sent when "GeofenceStatus.DWELL" is activated? Thanks!

ForegroundServiceDidNotStartInTimeException - Context.startForegroundService() did not then call Service.startForeground()

An error popped up in Crashtlytics on our production env. I opened a new issue for further investigation.

Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{...

Brand:Samsung
Model:Galaxy Z Fold3 5G
Version:Android 13

See StackTrace from Crashlytics
# Crashlytics - Stack trace
# Application: com.example.app
# Platform: android
# Version: 3.0.5 (577)
# Issue: 09bb529dadf96b173165f5972dd4308b
# Session: 6576CDC503420001716854EBA52ED2D8_DNE_0_v2
# Date: Mon Dec 11 2023 11:53:44 GMT+0300 (GMT+03:00)

Fatal Exception: android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{8df5c85 u0 com.example.app/com.pravera.flutter_foreground_task.service.ForegroundService}
      at android.app.ActivityThread.generateForegroundServiceDidNotStartInTimeException(ActivityThread.java:2251)
      at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:2222)
      at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException()
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2518)
      at android.os.Handler.dispatchMessage(Handler.java:106)
      at android.os.Looper.loopOnce(Looper.java:226)
      at android.os.Looper.loop(Looper.java:313)
      at android.app.ActivityThread.main(ActivityThread.java:8810)
      at java.lang.reflect.Method.invoke(Method.java)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

Caused by android.app.StackTrace: Last startServiceCommon() call for this service was made here
      at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1988)
      at android.app.ContextImpl.startForegroundService(ContextImpl.java:1933)
      at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:839)
      at q0.a$f.b()
      at q0.a.p()
      at com.pravera.flutter_foreground_task.service.a.d(:39)
      at ed.b.onMethodCall(:139)
      at ue.j$a.a(:17)
      at ie.c.l(:18)
      at ie.c.m(:40)
      at ie.c.i()
      at ie.b.run(:12)
      at android.os.Handler.handleCallback(Handler.java:942)
      at android.os.Handler.dispatchMessage(Handler.java:99)
      at android.os.Looper.loopOnce(Looper.java:226)
      at android.os.Looper.loop(Looper.java:313)
      at android.app.ActivityThread.main(ActivityThread.java:8810)
      at java.lang.reflect.Method.invoke(Method.java)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

Crashlytics Exception Handler1:
      at dalvik.system.VMStack.getThreadStackTrace(VMStack.java)
      at java.lang.Thread.getStackTrace(Thread.java:1841)
      at java.lang.Thread.getAllStackTraces(Thread.java:1909)
      at t9.v.z(:16)
      at t9.v.o(:4)
      at t9.v.j(:45)
      at t9.v.d(:44)
      at t9.u0.r(:19)
      at t9.u0.s(:32)
      at t9.r$b.a(:49)
      at t9.r$b.call()
      at t9.o$c.a(:2)
      at e8.x.run(:8)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
      at t9.b0$a$a.a(:2)
      at t9.e.run(:5)
      at java.lang.Thread.run(Thread.java:1012)

Remove Notification

How to remove the notifications (from the method WillStartForegroundTask() ) for Android devices? For iOS I just set showNotification = false. But there is not (or I haven't found it yet) a similar approach for Android notifications. If I remove the notifications in the "WillStartForegroundTask" method (or set them to zero, i.e. androidNotificationOptions: null), the app crashes as soon as I leave it

Upgrade dependency

Can you provide an update for this plugin with an upgrade of Geolocator dependency to ^7.0.1 version?

ForegroundService Exception

When clicking on a notification triggered by onGeofenceStatusChanged, I get following error:

android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{845dc41 u0 com.example.xxx/com.pravera.geofence_service.foreground_service.ForegroundSer
vice}

I implemented the plugin according to your guide and also changed the AndroidManifest.xml.
The notification is accomplished with the flutter_local_notifications package, but the error seems to be within this package.

unable to get any notification

I am using this package in my project. I have added all dependencies mentioned in the Read.me but there is no notification shown on my mobile when geofence trigger .Dev logs shows the status change of geofence but no notification is visible. Can anyone help me with this

ForegroundTask is always on

I am asking the user for permission to track the location always or only while using the app via permission_handler package. I am storing this bool in a global variable. How can I prevent the ForegroundTask to start when the permission for the background is not given?
At the moment the pin in the statusbar disappears for 1 second when closing the app, but appears again immediately afterwards.

How can I prevent the app from using the location when being closed?

InkedWhatsApp Image 2021-11-12 at 18 13 35_LI

This is my code:

      `@override
           Widget build(BuildContext context) {
               return WillStartForegroundTask(
                     onWillStart: () {
                         // You can add a foreground task start condition.

                           if (permissions.background.value) {
                                      print("ONWILLSTART");
                          
                                      return true;
                                    } else {
                                      print("ONWILLSTARTNOT");
                          
                                      return false;
                                    }
        },`

When closing the app it prints "ONWILLSTARTNOT", but the notification disappears and comes back immediately.

Any idea what I am doing wrong?

Updating the data on iOS

In Android (according to the default settings in the interval of 5000 milliseconds), the data is output to the console after the specified time. On iOS, however, this only happens once when the app is opened and then no longer. Is this a bug with the iOS simulator or is this normal? I always run it via Xcode (for Android via Visual Studio Code). Thanks !

WillStartForegroundTask blocks WillPopScope

The onWillPop method of WillPopScope is ignored when the child is WillStartForegroundTask.
Also reordering the widget tree does not help. When removing WillStartForegroundTask from the widget, WillPopScope is working as expected.

WillPopScope(
        onWillPop: () async {
          print("POP"); 
          Navigator.of(context).maybePop();
          return false;
        },
          child: 
               WillStartForegroundTask(
                onWillStart: () async {
                 ...

I want to run Geofence_Service in the background

μ•ˆλ…•ν•˜μ„Έμš”,
Geofence serviceλ₯Ό λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μ‹€ν–‰ν•˜λŠ” 방법에 λŒ€ν•΄ 문의 λ“œλ¦½λ‹ˆλ‹€.
ν˜„μž¬, μ–΄ν”Œμ„ μ’…λ£Œν•˜λ©΄ geofence service도 μ’…λ£Œλ˜μ–΄λ²„λ¦¬λŠ” μƒν™©μž…λ‹ˆλ‹€. 이λ₯Ό μ•„λž˜μ™€ 같이 ν•΄κ²°ν•˜κ³  싢은데 방법을 잘 λͺ°λΌμ„œ λ¬Έμ˜λ“œλ¦½λ‹ˆλ‹€.
1 geofence serviceλ₯Ό 5λΆ„ κ°„κ²©μœΌλ‘œ λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μ‹€ν–‰μ‹œν‚€κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.
2 geofence 반경 μ•ˆμ— μœ μ €κ°€ λ“€μ–΄κ°ˆ 경우 local notification이 였게 ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. (μ–΄ν”Œ μ‹€ν–‰ 쀑이 아닐 λ•Œλ„ local notification이 μ˜€λ„λ‘ ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.)
μœ„ 두가지 사항이 geofence νŒ¨ν‚€μ§€μ—μ„œ κ°€λŠ₯ν•œμ§€, λ˜ν•œ κ°€λŠ₯ν•˜λ‹€λ©΄ κ·Έ 방법에 λŒ€ν•΄ μ•Œλ €μ£Όμ‹œλ©΄ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.
λ°”μ˜μ‹  와쀑에 문의 λ“œλ € μ£„μ†‘ν•©λ‹ˆλ‹€.
κ°μ‚¬ν•©λ‹ˆλ‹€.

I am having trouble getting Geofence_Service to stop when I kill the app.
The two functions we would like to achieve are.
1.I would like to run Geofence_Service in the background at 5 minute intervals.
2.I would like to send out a local notification when a Geofence is crossed.

Cannot build example add on iOS

I'm trying to build the example app on my macbook but it does not seem to be working.

Steps taken:

  1. Create a new flutter project using flutter create
  2. Update dependencies in pubspec.yml
  3. Copy the code from main.dart in the example to my own project
  4. Build using flutter build ios

Error:
CFURLRequestSetHTTPCookieStorageAcceptPolicy_block_invoke: no longer
implemented and should not be called
** BUILD FAILED **

Using Xcode 12 and MacOS Big Sur

java.lang.IncompatibleClassChangeError: Found interface com.google.android.gms.location.SettingsClient,

Hi, can you check whats this problem on this case
I got forced closed app then i have error this like this

java.lang.IncompatibleClassChangeError: Found interface com.google.android.gms.location.SettingsClient, but class was expected (declaration of 'com.google.android.gms.location.SettingsClient' appears in /data/app/com.kiatanandagroup.driver-UsfQeG2gVgt3Cq3AzhaG7Q==/base.apk) E/AndroidRuntime(12461): at com.pravera.fl_location.service.LocationDataProvider.checkLocationSettingsAndStartLocationUpdates(LocationDataProvider.kt:68) E/AndroidRuntime(12461): at com.pravera.fl_location.service.LocationDataProvider.requestLocationUpdates(LocationDataProvider.kt:60) E/AndroidRuntime(12461): at com.pravera.fl_location.service.LocationDataProviderManager.requestLocationUpdates(LocationDataProviderManager.kt:47) E/AndroidRuntime(12461): at com.pravera.fl_location.LocationStreamHandlerImpl.onListen(LocationStreamHandlerImpl.kt:39) E/AndroidRuntime(12461): at io.flutter.plugin.common.EventChannel$IncomingStreamRequestHandler.onListen(EventChannel.java:218) E/AndroidRuntime(12461): at io.flutter.plugin.common.EventChannel$IncomingStreamRequestHandler.onMessage(EventChannel.java:197) E/AndroidRuntime(12461): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295) E/AndroidRuntime(12461): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:319) E/AndroidRuntime(12461): at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$TsixYUB5E6FpKhMtCSQVHKE89gQ.run(Unknown Source:12) E/AndroidRuntime(12461): at android.os.Handler.handleCallback(Handler.java:883) E/AndroidRuntime(12461): at android.os.Handler.dispatchMessage(Handler.java:100) E/AndroidRuntime(12461): at android.os.Looper.loop(Looper.java:237) E/AndroidRuntime(12461): at android.app.ActivityThread.main(ActivityThread.java:8034) E/AndroidRuntime(12461): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime(12461): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) E/AndroidRuntime(12461): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076) I/Process (12461): Sending signal. PID: 12461 SIG: 9

Not working when app is removed

When app is minimised and in foreground everything work fine but when app is closed location update and geofence both not working.

Getting below error -

Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: plugins.pravera.com/fl_location/updates. Response ID: 0

Service runs in background even if app is killed

I am using WillStartForegroundTask to check the location when the app is paused or inactive. But I want it to be killed, when the app is killed via task manager. Currently I still get the push notification that the app is still runnning in the background, even if it is complelety closed an not shown in the task manager of my android device.

WillStartForegroundTask(
onWillStart: () {
// You can add a foreground task start condition.
return geofenceService.isRunningService;
},
androidNotificationOptions: AndroidNotificationOptions(
channelId: 'geofence_service_notification_channel',
channelName: 'Geofence Service Notification',
channelDescription:
'This notification appears when the geofence service is running in the background.',
channelImportance: NotificationChannelImportance.HIGH,
priority: NotificationPriority.HIGH),
iosNotificationOptions: IOSNotificationOptions(),
notificationTitle: 'Aschaffenburger Geheimnisse lΓ€uft im Hintergrund',
notificationText: 'Klicke, um in die App zurΓΌckzukehren!',
child:
AnnotatedRegion(
value: SystemUiOverlayStyle.light,
child:
Container();
));

Doesn't build on android emulator

Error when building for android emulator

Launching lib\main.dart on sdk gphone x86 arm in debug mode...
lib\main.dart:1
e: D:\Flutter.io\flutter\.pub-cache\hosted\pub.dartlang.org\flutter_activity_recognition-1.2.0\android\src\main\kotlin\com\pravera\flutter_activity_recognition\service\ActivityRecognitionManager.kt: (91, 59): Unresolved reference: S
e: D:\Flutter.io\flutter\.pub-cache\hosted\pub.dartlang.org\flutter_activity_recognition-1.2.0\android\src\main\kotlin\com\pravera\flutter_activity_recognition\service\ActivityRecognitionManager.kt: (92, 65): Unresolved reference: FLAG_MUTABLE

Verson: geofence_service: ^3.4.4

build.gradle has these in default config

        minSdkVersion 27
        targetSdkVersion 30
        multiDexEnabled true
$ flutter doctor -v
[√] Flutter (Channel stable, 2.5.3, on Microsoft Windows [Version 10.0.19042.1348], locale en-GB)
    β€’ Flutter version 2.5.3 at D:\Flutter.io\flutter
    β€’ Upstream repository https://github.com/flutter/flutter.git
    β€’ Framework revision 18116933e7 (6 weeks ago), 2021-10-15 10:46:35 -0700
    β€’ Engine revision d3ea636dc5
    β€’ Dart version 2.14.4

... No issues

Multiple _geofenceServices

Is there a way to create multiple _geofenceServices and run them both? I want to have two geofence-Services with a different loiteringDelayMs. Thanks!

fl_location version needs to be updated

Cuikd errors occurring when adding geofence_service

\fl_location-1.2.2\android\src\main\kotlin\com\pravera\fl_location\service\LocationDataProvider.kt: (137, 23): Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Location? etc

Resolved by updating the fl_location version.

PR added #27

Optional Activity Stream

I removed the activity permissions and the setOnActivityChanged once I don't have a real use for those data. But when I call the service the app crashes and returns "[access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMotionUsageDescription key with a string value explaining to the user how the app uses this data.". Is there a way to prevent this? Thank you

By the way, I am currently on version 1.0.3 because this app is still in flutter 1.22.6

Geofence_service breaks local notifications on iOS

When using geofence_service together with flutter_local_notifications, when you minimize the app on an iOS device, the local notifications no longer trigger methods on notification clicks.

The breaking point on this issue (as far as I can tell) is on the app minimize, notification clicks trigger correctly if you start the app and never minimize it or if you stop the geofence_service before the first app minimize.

After the app minimizes once with the geofence_service on, I can no longer get the notifications to trigger any methods on click.

Steps to reproduce:

  1. get the example app from flutter_local_notifications
  2. add geofence_service package
  3. set it up so the geofence_service and the foreground task starts on the first screen of the app
    3.1*) there appears an error on one of the notification showcases when you add geofence_service package, can comment over that method since it wont be used for the test.
  4. start up the app on an iOS device
  5. send a notification via the app and click it. This should redirect to 2nd page of the app (works correctly)
  6. minimize the app and go back to it
  7. send a notification via the app and click it -> nothing happens (notification breaks)

Any help on this would be greatly appreciated.

not working in the background

OS: Android s10

Can you provide an example code that shows how to use the library in the background?

does not work in the background state.

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[βœ“] Flutter (Channel stable, 3.10.2, on macOS 13.3.1 22E772610a darwin-arm64, locale ko-KR)
[βœ“] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[βœ“] Xcode - develop for iOS and macOS (Xcode 14.2)
[βœ“] Chrome - develop for the web
[βœ“] Android Studio (version 2022.2)
[βœ“] IntelliJ IDEA Ultimate Edition (version 2023.1.2)
[βœ“] IntelliJ IDEA Ultimate Edition (version 2023.1.2)
[βœ“] IntelliJ IDEA Ultimate Edition (version 2022.3.3)
[βœ“] IntelliJ IDEA Ultimate Edition (version 2023.1.1)
[βœ“] VS Code (version 1.78.2)
[βœ“] Connected device (3 available)
[βœ“] Network resources

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.