transistorsoft / flutter_background_geolocation

Sophisticated, battery-conscious background-geolocation & geofencing with motion-detection
https://www.transistorsoft.com/shop/products/flutter-background-geolocation
Other
647 stars 240 forks source link

OnGeofence events never triggering with polygon geofencing on Android #1171

Closed emlil closed 11 months ago

emlil commented 11 months ago

Your Environment


## Expected Behavior
OnGeofence should fire Entry/Exit events 
## Actual Behavior
<!--- Tell us what happens instead -->
Nothing, onGeofence is unresponsive while geofences are polygonal
## Steps to Reproduce
<!--- reproduce this issue; include code to reproduce, if relevant -->
1. Build in debug mode
2. Setup Geofencing listeners; onGeofence, onLocation
3.run "ready" with config
4.insert polygonal geofences
4a. Be inside geofence, initialTriggerEntry does not trigger onGeofence
4b. Move inside a geofence, onGeofence does not trigger 

## Context
<!--- What were you trying to do? -->
With the inclusion of support for polygonal geofences we are trying to implement the use of those instead of circular geofences to be able to more accurately rely on onGeofence to know if a user is inside of an area.
So far it seems to work on iOS but on Android nothing happens when we change the circular geofences for polygonal.
I see that the logs contain some  ║ Geofencing Event: ENTER
but they never reach the onGeofence listener

## Debug logs
<!-- include iOS / Android logs
- ios XCode logs,
- use #getLog #emailLog methods (@see docs)
- Android: $ adb logcat -s TSLocationManager
-->
<details>
    <summary>Logs</summary>

``` <!-- syntax-highligting:  DO NOT REMOVE -->
╔═════════════════════════════════════════════
║ TSLocationManager3.5.2 (431)
╠═════════════════════════════════════════════
╟─ Google Pixel 7 Pro @ 13 (flutter)
{
  "activityRecognitionInterval": 10000,
  "allowIdenticalLocations": false,
  "authorization": {},
  "autoSync": true,
  "autoSyncThreshold": 0,
  "backgroundPermissionRationale": {
    "title": "Allow {applicationName} to access this device's location in the background?",
    "message": "In order to check you in and out of sites in the background, please enable {backgroundPermissionOptionLabel} location permission",
    "positiveAction": "Change to {backgroundPermissionOptionLabel}",
    "negativeAction": "Cancel"
  },
  "batchSync": false,
  "configUrl": "",
  "debug": true,
  "deferTime": 0,
  "desiredAccuracy": 10,
  "desiredOdometerAccuracy": 100,
  "disableAutoSyncOnCellular": false,
  "disableElasticity": true,
  "disableLocationAuthorizationAlert": false,
  "disableMotionActivityUpdates": false,
  "disableProviderChangeRecord": false,
  "disableStopDetection": false,
  "distanceFilter": 50,
  "elasticityMultiplier": 1,
  "enableHeadless": false,
  "enableTimestampMeta": false,
  "extras": {},
  "fastestLocationUpdateInterval": -1,
  "foregroundService": true,
  "geofenceInitialTriggerEntry": true,
  "geofenceModeHighAccuracy": true,
  "geofenceProximityRadius": 1000,
  "geofenceTemplate": "",
  "headers": {},
  "headlessJobService": "com.transistorsoft.flutter.backgroundgeolocation.HeadlessTask",
  "heartbeatInterval": -1,
  "httpRootProperty": "location",
  "httpTimeout": 60000,
  "isMoving": false,
  "locationAuthorizationRequest": "WhenInUse",
  "locationTemplate": "",
  "locationTimeout": 60,
  "locationUpdateInterval": 5000,
  "locationsOrderDirection": "ASC",
  "logLevel": 5,
  "logMaxDays": 1,
  "maxBatchSize": -1,
  "maxDaysToPersist": 1,
  "maxMonitoredGeofences": 97,
  "maxRecordsToPersist": -1,
  "method": "POST",
  "minimumActivityRecognitionConfidence": 75,
  "motionTriggerDelay": 0,
  "notification": {
    "layout": "",
    "title": "",
    "text": "Location Service activated",
    "color": "",
    "channelName": "TSLocationManager",
    "channelId": "",
    "smallIcon": "",
    "largeIcon": "",
    "priority": -1,
    "sticky": false,
    "strings": {},
    "actions": []
  },
  "params": {},
  "persist": true,
  "persistMode": 2,
  "schedule": [],
  "scheduleUseAlarmManager": false,
  "speedJumpFilter": 300,
  "startOnBoot": false,
  "stationaryRadius": 25,
  "stopAfterElapsedMinutes": 0,
  "stopOnStationary": false,
  "stopOnTerminate": true,
  "stopTimeout": 5,
  "triggerActivities": "in_vehicle, on_bicycle, on_foot, running, walking",
  "url": "",
  "useSignificantChangesOnly": false,
  "enabled": true,
  "schedulerEnabled": false,
  "trackingMode": 0,
  "odometer": 0,
  "isFirstBoot": true,
  "didLaunchInBackground": false,
  "didDeviceReboot": false
}
╔═════════════════════════════════════════════
║ DEVICE SENSORS
╠═════════════════════════════════════════════
╟─ ✅  ACCELEROMETER: {Sensor name="LSM6DSV Accelerometer", vendor="STMicro", version=1, type=1, maxRange=156.9064, resolution=0.0047856453, power=0.001, minDelay=5000}
╟─ ✅  GYROSCOPE: {Sensor name="LSM6DSV Gyroscope", vendor="STMicro", version=1, type=4, maxRange=34.906063, resolution=0.0012217305, power=0.001, minDelay=5000}
╟─ ✅  MAGNETOMETER: {Sensor name="Fusion Mag", vendor="Google", version=1, type=2, maxRange=3198.1567, resolution=0.0976, power=0.001, minDelay=10000}
╟─ ✅  SIGNIFICANT_MOTION: {Sensor name="Significant Motion (wake-up)", vendor="Google", version=1, type=17, maxRange=1.0, resolution=1.0, power=0.001, minDelay=-1}
╚═════════════════════════════════════════════ 

background-geolocation (3).log

christocracy commented 11 months ago

locationAuthorizationRequest: "WhenInUse",

Both iOS and Android require Always authorization for geofencing.

emlil commented 11 months ago

@christocracy even though it is set to this in config, the testing has been done with the permission set to always. Is this setting still relevant then?

christocracy commented 11 months ago

Show me the vertices of this polygon SITE0p7gzujjd1675331538234

11-09 12:28:50.414 INFO [GeofencingService a] 
╔═════════════════════════════════════════════
║ Geofencing Event: ENTER
╠═════════════════════════════════════════════
╟─ ENTER containing geofence of Polygon: SITE0p7gzujjd1675331538234 buffer
╚═════════════════════════════════════════════
╔═════════════════════════════════════════════
║ isInPolygon: 📍  60.38281687922973, 5.308061099753924, acy: 3.9m
╠═════════════════════════════════════════════
11-09 12:28:52.027 DEBUG [TSGeofence isLocationInPolygon] --> SITE0p7gzujjd1675331538234 buffer: 0.0%

You can see the polygon evaluator operating in the logs here, reporting that 0.0% of the current location resides within the polygon.

The way the polygon evaluator operates is by drawing a circle around the current location of radius accuracy meters (in this case 3.9m, then computing 16 points around that circle. When 40% of the 16 points are within the polygon, the ENTER event will be fired.

I suspect you've created too small of a polygon.

christocracy commented 11 months ago

Here are some images to show how this works.

Case 1: Current location is OUTSIDE of Polygon.

In the first image, there are only 5 of 16 "boundary points" within the polygon. 5 / 16 = ~31%. The location is not considered to have entered the polygon.

polygon-geofence-OUT

Case 2: Location is INSIDE Polygon:

In the next image, there are 9 of 16 "boundary points" within the polygon. The current location is considered to have ENTERed the polygon: 9 / 16 = ~56%

polygon-geofence-ENTER

So, when you see this in the logs:

╔═════════════════════════════════════════════
║ isInPolygon: 📍  60.38281687922973, 5.308061099753924, acy: 3.9m
╠═════════════════════════════════════════════
[TSGeofence isLocationInPolygon] --> SITE0p7gzujjd1675331538234 buffer: 0.0%
emlil commented 11 months ago

Here are the vertices

[[60.38230286513362, 5.303395185529516], [60.38244023767629, 5.303405600991172], [60.3825337587921, 5.303609473409488], [60.382657036853956, 5.304281134786446], [60.382660543085436, 5.3045132171610945], [60.38252931158423, 5.305388726423183], [60.38246441079633, 5.305575204807774], [60.382357382464, 5.305646751455249], [60.38195738377663, 5.305646751455249], [60.38184236927869, 5.305562495717216], [60.38178066741885, 5.305348783541836], [60.38173559733897, 5.304851465750848], [60.38173265574079, 5.304783154512104], [60.38173530692368, 5.304071259999923], [60.38176786945291, 5.303865262316839], [60.38185249410989, 5.303733143865392], [60.38230286513362, 5.303395185529516]]

christocracy commented 11 months ago
Screenshot 2023-11-09 at 11 11 30 AM
christocracy commented 11 months ago

Btw, you don't need to "close a polygon" by ending your vertices with a copy of the first [60.38230286513362, 5.303395185529516]. Polygon's are auto-closed.

emlil commented 11 months ago

I've now updated the geofence, its almost three times the original size. And i walked through the site GEOF

Here's the vertices

(
[60.38318063075226, 5.30255789249031]
[60.383318509253094, 5.302661544592356]
[60.38337192056702, 5.302938857846105]
[60.383336319758925, 5.304375378182343]
[60.383327071706326, 5.306670196084874]
[60.383265112133905, 5.306941907724499]
[60.38312341027312, 5.307027521072812]
[60.3816682604143, 5.306630554138608]
[60.38156787198031, 5.306532581740304]
[60.38151535441579, 5.306333660172467]
[60.38138544531188, 5.3048492894639985]
[60.38138327892702, 5.304756546992615]
[60.38144955914681, 5.303100514907193]
[60.38150253811331, 5.302870899386415]
[60.38161678363834, 5.302767104793472]
[60.38318063075226, 5.30255789249031]
)

In the log this time there are no mentions of the polygon for SITE0p7gzujjd1675331538234 except for in creation of the polygon. There are a lot of events for another site:

11-09 17:38:26.629 DEBUG [PolygonGeofencingService c] 
╔═════════════════════════════════════════════
║ isInPolygon: 📍  60.3820087, 5.3050213, acy: 3.91m
╠═════════════════════════════════════════════

11-09 17:38:26.630 DEBUG [TSGeofence isLocationInPolygon] --> SITEneyk7lz741686640742230 buffer: 0.0% 

But they are checking a location thats inside the first mentioned polygon: SITE0p7gzujjd1675331538234

background-geolocation (2).log.gz

christocracy commented 11 months ago

I see unknown problems with the plugin's calculation of the "minimum enclosing circle" (the native circular geofence that encloses your polygon).

11-09 17:34:48.824 DEBUG [TSGeofence$Builder build] [MiniBall] Minimum Enclosing Circle: 0.0 / 0.0, radius0.0
11-09 17:34:48.825 DEBUG [TSGeofence$Builder build] [MiniBall] Minimum Enclosing Circle: 0.0 / 0.0, radius1.17E-321
christocracy commented 11 months ago

When I create a Polygon using your coordinates:

[60.38318063075226, 5.30255789249031]
[60.383318509253094, 5.302661544592356]
[60.38337192056702, 5.302938857846105]
[60.383336319758925, 5.304375378182343]
[60.383327071706326, 5.306670196084874]
[60.383265112133905, 5.306941907724499]
[60.38312341027312, 5.307027521072812]
[60.3816682604143, 5.306630554138608]
[60.38156787198031, 5.306532581740304]
[60.38151535441579, 5.306333660172467]
[60.38138544531188, 5.3048492894639985]
[60.38138327892702, 5.304756546992615]
[60.38144955914681, 5.303100514907193]
[60.38150253811331, 5.302870899386415]
[60.38161678363834, 5.302767104793472]
[60.38318063075226, 5.30255789249031]

My logs show:

[MiniBall] Minimum Enclosing Circle: 60.3826828841048 / 5.304786700866407, radius 253.93713971114747

I think you must be providing bad vertices on the device you're testing on.

christocracy commented 11 months ago

This is your polygon vertices and the calculated enclosing circle:

Screenshot 2023-11-09 at 1 02 47 PM
christocracy commented 11 months ago

I suggest you test your data with addGeofence and pay close attention to the MiniBall logs calculating the enclosing circle. You should never see a latitude/longitude of 0, 0.

[MiniBall] Minimum Enclosing Circle

emlil commented 11 months ago

Alright. I ran the app only creating a single geofence

 bg.BackgroundGeolocation.addGeofence(bg.Geofence(
        identifier: 'test',
        vertices: [
          [60.38318063075226, 5.30255789249031],
        [60.383318509253094, 5.302661544592356],
        [60.38337192056702, 5.302938857846105],
        [60.383336319758925, 5.304375378182343],
        [60.383327071706326, 5.306670196084874],
        [60.383265112133905, 5.306941907724499],
        [60.38312341027312, 5.307027521072812],
        [60.3816682604143, 5.306630554138608],
        [60.38156787198031, 5.306532581740304],
        [60.38151535441579, 5.306333660172467],
        [60.38138544531188, 5.3048492894639985],
        [60.38138327892702, 5.304756546992615],
        [60.38144955914681, 5.303100514907193],
        [60.38150253811331, 5.302870899386415],
        [60.38161678363834, 5.302767104793472],
        [60.38318063075226, 5.30255789249031]],
        notifyOnEntry: true,
        notifyOnExit: true,
      )
      );

Creating a geofence like this gives the same result: D/TSLocationManager( 7824): [c.t.l.g.TSGeofence$Builder build] [MiniBall] Minimum Enclosing Circle: 0.0 / 0.0, radius0.0 However, creating polygonal geofences in your example app on the same device seems to work: D/TSLocationManager(14489): [c.t.l.g.TSGeofence$Builder build] [MiniBall] Minimum Enclosing Circle: 60.38288617717974 / 5.3080188391343945, radius60.54230040772544

The same is the case when trying it out in a basic app with only geofencing.

Sometimes the MiniBall logs a really strange radius. Might be an int overflow? D/TSLocationManager(11765): [c.t.l.g.TSGeofence$Builder build] [MiniBall] Minimum Enclosing Circle: 0.0 / 0.0, radius1.0E-323

Do you have any clue what our app does wrong?

christocracy commented 11 months ago

Do you have any clue what our app does wrong?

Did you purchase a license for Polygon Geofencing? Are you testing your app with a "release" or "debug" build?

emlil commented 11 months ago

We've not purchased a license yet. We are running the app in debug mode However this message appears when we start building [flutter_background_geolocation] Purging debug resources in release build

christocracy commented 11 months ago

However this message appears when we start building

This doesn't mean your app is building for release. This is just the plugin iterating through all variants (debug and release) and adding a method.

christocracy commented 11 months ago

I've added some debug output during MiniBall process that I need to see you execute.

Please modify your pubspec.yaml to load the plugin from the git as follows:

dependencies:
  flutter_background_geolocation:
    git:
      url: https://github.com/transistorsoft/flutter_background_geolocation.git
      ref: miniball-error

Remove / re-add your gefence(s).

From your logs, I'm interested in seeing the new *** IS DEBUG? 1 || 0 output:

V/TSLocationManager(14881): *** IS DEBUG? 1
V/TSLocationManager(14881): [MiniBall] Circle coordinate: 60.382683, 5.304787, radius: 253.937140
V/TSLocationManager(14881): [MiniBall] squared_radius: 0.000005, corrected radius: 253.937140
V/TSLocationManager(14881): [MiniBall] isValid?: 0, error: 0.000000
emlil commented 11 months ago

Running this version provides me with V/TSLocationManager(16555): *** IS DEBUG? 0

christocracy commented 11 months ago

This is the problem. Why does your app think it's not running as a DEBUG build? The plugin MiniBall process purposely returns incorrect data when the app is run as a RELEASE build without a polygon-geofencing license key.

How are you building / launching your app?

emlil commented 11 months ago

Doing print(kDebugMode); return true though. How come this is different? I'm using android studio and launching the app in debug mode through its UI (the debug button)

christocracy commented 11 months ago

What is kDebugMode?

christocracy commented 11 months ago

Launch your app from console:

$ flutter run
emlil commented 11 months ago

What is kDebugMode?

Its a constant that is true if the app is built in debug mode (source)

christocracy commented 11 months ago

I don't think that is necessarily related to the Android build variant. That's related to the dart code.

emlil commented 11 months ago

Our app relies on flavors, doing flutter run --flavor staging also returns V/TSLocationManager(19317): *** IS DEBUG? 0

christocracy commented 11 months ago
$ flutter run --flavor stagingDebug
emlil commented 11 months ago

Now im doing $ flutter run --flavor stagingDebug running gradle task assembleStagingDebugDebug building and installing the apk file app-stagingdebug-debug.apk

My build is very debug now but I still get V/TSLocationManager( 9134): *** IS DEBUG? 0 and D/TSLocationManager( 9134): [c.t.l.g.TSGeofence$Builder build] [MiniBall] Minimum Enclosing Circle: 0.0 / 0.0, radius: 0.0

christocracy commented 11 months ago

I see a problem. I've pushed another commit to branch miniball-error.

Do a flutter pub get and run the following:

$ flutter run --flavor staging --debug
emlil commented 11 months ago

This seems to have solved the issue!