DwayneCoussement / flutter_geofence

BSD 3-Clause "New" or "Revised" License
42 stars 40 forks source link

Geofence.startListening not working #5

Open prabhunath111 opened 4 years ago

prabhunath111 commented 4 years ago

Why the Geofence.startListening method is not calling?

DwayneCoussement commented 4 years ago

Hey, can you provide me more information here? I’d love to help out!

For starters: was this Android or iOS?

Did you call Geofence.initialize and did you get a callback that your regions were registered?

prabhunath111 commented 4 years ago

I am using android, I am sharing my code, Can you check it? Whenever I am going outside from region I am not getting notification.

import 'package:flutter/material.dart'; import 'dart:async'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_geofence/geofence.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); }

class _MyAppState extends State { String _platformVersion = 'Unknown';

FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();

@override void initState() { super.initState(); initPlatformState();

// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project var initializationSettingsAndroid = new AndroidInitializationSettings('app_icon'); var initializationSettingsIOS = IOSInitializationSettings( onDidReceiveLocalNotification: null); var initializationSettings = InitializationSettings( initializationSettingsAndroid, initializationSettingsIOS); flutterLocalNotificationsPlugin.initialize(initializationSettings, onSelectNotification:null);

}

// Platform messages are asynchronous, so we initialize in an async method. Future initPlatformState() async { print('Inside initPlatformState'); // If the widget was removed from the tree while the asynchronous platform // message was in flight, we want to discard the reply rather than calling // setState to update our non-existent appearance. if (!mounted) return; Geofence.initialize(); Geofence.startListening(GeolocationEvent.entry, (entry) { print("startlistening"); scheduleNotification("Entry of a georegion", "Welcome to: ${entry.id}"); });

Geofence.startListening(GeolocationEvent.exit, (entry) {
  print('startlistening exit');
  scheduleNotification("Exit of a georegion", "Byebye to: ${entry.id}");
});

setState(() {

});

}

@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Plugin geofence'), ), body: ListView(children: [ Text('Running on: $_platformVersion\n'), RaisedButton(child: Text("Add region"), onPressed: () { Geolocation location = Geolocation(latitude: 22.5861973, longitude: 88.4075299, radius: 0.000005, id: "Kerkplein13"); Geofence.addGeolocation(location, GeolocationEvent.entry).then((onValue) { print("great success"); scheduleNotification("Georegion added", "Your geofence has been added!"); }).catchError((onError) { print("great failure"); }); },), RaisedButton(child: Text("get user location"), onPressed: () {

        Geofence.getCurrentLocation().then((coordinate) {

          print("great got latitude: ${coordinate.latitude} and longitude: ${coordinate.longitude}");

        });
      })
    ],
    ),
  ),
);

}

void scheduleNotification(String title, String subtitle) {

Future.delayed(Duration(seconds: 3)).then((result) async {

  var androidPlatformChannelSpecifics = AndroidNotificationDetails(
      'Kerkplein13', 'your channel name', 'your channel description',
      importance: Importance.Max, priority: Priority.High, ticker: 'ticker');

  var iOSPlatformChannelSpecifics = IOSNotificationDetails();

  var platformChannelSpecifics = NotificationDetails(
      androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);

  await flutterLocalNotificationsPlugin.show(
      0, title, subtitle, platformChannelSpecifics,
      payload: 'item x');
});

} }

DwayneCoussement commented 4 years ago

Hey, are you running the example app or did you copy that into your app? if so, dont forget to add the things mentioned in the github readme to your AndroidManifest.xml, see also the example app.

prabhunath111 commented 4 years ago

yeah, I am using this code in my app and also I am adding things in the manifest. I am not getting that what is the channel id, channel name and channel description, can you clear it how to generate all these?

Showing error Unresolved class GeofenceBroadcastReceiver And also unresolved class GeofencePlugin when I am adding receiver and services in manifest.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.geofence">

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

<application
    android:name="io.flutter.app.FlutterApplication"
    android:label="geofence"
    android:icon="@mipmap/ic_launcher">

    <activity
        android:name=".MainActivity"
        android:launchMode="singleTop"
        android:theme="@style/LaunchTheme"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

    <receiver android:name="com.example.geofence.GeofenceBroadcastReceiver"
        android:enabled="true"
        android:exported="true"/>
    <service android:name="com.example.geofence.GeofencePlugin"
        android:permission="android.permission.BIND_JOB_SERVICE"
        android:exported="true"/>
    <!-- Don't delete the meta-data below.
         This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
    <meta-data
        android:name="flutterEmbedding"
        android:value="2" />
</application>

DwayneCoussement commented 4 years ago

channel id, channel name and channel description are related to the example app, check the referenced library at: https://pub.dev/packages/flutter_local_notifications

Running the app locally shows me necessary callbacks happen.

prabhunath111 commented 4 years ago

I am using your example code I am giving code snippet here for startListening method and logger also Can you please check here why I am getting null ...

/// Set a callback block for a specific geo-event

static void startListening(GeolocationEvent event, GeofenceCallback entry) { print('event $event entry $entry'); switch (event) { case GeolocationEvent.entry: _entryCallback = entry; break; case GeolocationEvent.exit: _exitCallback = entry; break; } }

I/flutter (27080): event GeolocationEvent.entry entry Closure: (Geolocation) => Null I/flutter (27080): event GeolocationEvent.exit entry Closure: (Geolocation) => Null

Also, I am getting one error in the manifest which showing in the screenshot

/home/aponiar-17/Pictures/Screenshot from 2020-02-10 17-32-58.png

SergejDK commented 4 years ago

@DwayneCoussement I have the same issue as @prabhunath111

I tried the example-app and the listening-function is not working on the emulator and on my real device.

On my device I have Android 9 running.

iOS is working good on phone and simulator.

SergejDK commented 4 years ago

I looked a bit into this and could not make it work till now. Just found out that the onReceive function of the GeofenceBroadcastReceiver is never called....

Shajeel-Afzal commented 4 years ago

startListening is not working, please fix this problem.

CurtesMalteser commented 4 years ago

Is working for me on Android. What I did was set a position on emulator outside of the Geofence, then set new position inside of it and exit the geofence again. Worked just fine. Maybe this can help. In fact I need to add something. On my previous statement I mentioned everything was working fine, but after enter the Geofence the exit callback isn't triggered. But in one event is added for entry and exit, only the latest will be triggered. Wasn't supposed to be notified after exit automatically?

debkanchan commented 4 years ago

Is working for me on Android. What I did was set a position on emulator outside of the Geofence, then set new position inside of it and exit the geofence again. Worked just fine. Maybe this can help. In fact I need to add something. On my previous statement I mentioned everything was working fine, but after enter the Geofence the exit callback isn't triggered. But in one event is added for entry and exit, only the latest will be triggered. Wasn't supposed to be notified after exit automatically?

I have tried that but it is still not working.

Edit: @DwayneCoussement Now it looks like even the example app is not working

kroobroeck commented 4 years ago

@prabhunath111 I just made a contribution as the example app also wasn't working for me. You can try it out and see if this fixes your problem. Basically, it had to do with the background permission.

debkanchan commented 4 years ago

@kroobroeck @DwayneCoussement Tested on Pixel 3a XL emulator with android R. Background permission is working and notifications are being delivered but still the core problem of startListening not firing is present.

Edit: Tested on device Asus Zenfone Max Pro M1 X100TD with android 10 and NOTHING worked. Again tested on Realme 5 RMX1911 with android 9 and everything worked perfectly.

Edit 2: Tested again on Pixel 3a XL emulator with android 10 and just like real device NOTHING worked.

prabhunath111 commented 4 years ago

@kroobroeck @DwayneCoussement Tested om Pixel 3a XL emulator with android R. Background permission is working and notifications are being delivered but still the core problem of startListening not firing is present.

Edit: Tested on device Asus Zenfone Max Pro M1 X100TD with android 10 and NOTHING worked. Again tested on Realme 5 RMX1911 with android 9 and everything worked perfectly.

Can you please provide code snippet to me it will very helpful to me?

debkanchan commented 4 years ago

@kroobroeck @DwayneCoussement Tested om Pixel 3a XL emulator with android R. Background permission is working and notifications are being delivered but still the core problem of startListening not firing is present. Edit: Tested on device Asus Zenfone Max Pro M1 X100TD with android 10 and NOTHING worked. Again tested on Realme 5 RMX1911 with android 9 and everything worked perfectly.

Can you please provide code snippet to me it will very helpful to me?

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_geofence/geofence.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';

  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();

  @override
  void initState() {
    super.initState();
    initPlatformState();

// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
    var initializationSettingsAndroid =
    new AndroidInitializationSettings('app_icon');
    var initializationSettingsIOS = IOSInitializationSettings(
        onDidReceiveLocalNotification: null);
    var initializationSettings = InitializationSettings(
        initializationSettingsAndroid, initializationSettingsIOS);
    flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: null);

  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;
    Geofence.initialize();
    Geofence.startListening(GeolocationEvent.entry, (entry) {
      scheduleNotification("Entry of a georegion", "Welcome to: ${entry.id}");
    });

    Geofence.startListening(GeolocationEvent.exit, (entry) {
      scheduleNotification("Exit of a georegion", "Byebye to: ${entry.id}");
    });

    setState(() {
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: ListView(children: <Widget>[
          Text('Running on: $_platformVersion\n'),
          RaisedButton(child: Text("Add region"), onPressed: () async {
            final Coordinate loc = await Geofence.getCurrentLocation();
            Geolocation location = Geolocation(latitude: loc.latitude, longitude: loc.longitude, radius: 1, id: "Kerkplein13");
            Geofence.addGeolocation(location, GeolocationEvent.entry).then((onValue) {
              print("great success");
              scheduleNotification("Georegion added", "Your geofence has been added!");
            }).catchError((onError) {
              print("great failure");
            });
          },),
          RaisedButton(child: Text("get user location"), onPressed: () {
              Geofence.getCurrentLocation().then((coordinate) {
                print("great got latitude: ${coordinate.latitude} and longitude: ${coordinate.longitude}");
              });
          })
        ],
        ),
      ),
    );
  }

  void scheduleNotification(String title, String subtitle) async
   {
    print(title + " " + subtitle);
    var androidPlatformChannelSpecifics = AndroidNotificationDetails(
          'your channel id', 'your channel name', 'your channel description',
          importance: Importance.Max, priority: Priority.High, ticker: 'ticker');
      var iOSPlatformChannelSpecifics = IOSNotificationDetails();
      var platformChannelSpecifics = NotificationDetails(
          androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
      await flutterLocalNotificationsPlugin.show(
          0, title, subtitle, platformChannelSpecifics,
          payload: 'item x');
  }

}
debkanchan commented 4 years ago

@kroobroeck @DwayneCoussement Tested on Pixel 3a XL emulator with android R. Background permission is working and notifications are being delivered but still the core problem of startListening not firing is present.

Edit: Tested on device Asus Zenfone Max Pro M1 X100TD with android 10 and NOTHING worked. Again tested on Realme 5 RMX1911 with android 9 and everything worked perfectly.

Edit 2: Tested again on Pixel 3a XL emulator with android 10 and just like real device NOTHING worked.

Re-Tested on Asus Zenfone Max Pro M1 X100TD with android 10 and everything works perfectly. Made a pixel 3a XL emulator with android 9 and nothing works there. Looks like there's a problem with Emmulators but I can confirm in real device re-test of both Asus Zenfone Max Pro M1 X100TD with android 10 and Realme 5 RMX1911 with android 9 plugin works correctly.

debkanchan commented 4 years ago

Update: Example app works perfectly but not the following implementation

locationService.dart

...

class LocationService {
  LocationService() {

   ... 
   Geofence.initialize();

    Geofence.startListening(GeolocationEvent.entry, (entry) {
      print(entry);
      _geofenceStream.add(entry);
    });
    ...
  }

orderService.dart

...
class Order {
    Order(DataSnapshot) {
    ...
    _geofenceSub = location.onGeofence.listen((data) async {
         print("I'm in");
         print(data);
         if (data.id == this._id && ride.stage == Stage.accepted) {
           print("I'm in 2");
           ride.stage = Stage.arrived;
           await GetIt.I<MessagingService>().sendNotification("Your Ride has Arrived", "Hop in and verify with OTP to start the ride");
           await sendOTP();
           _geofenceSub.cancel();
         }
       });
   ...
     }

}
DwayneCoussement commented 4 years ago

Hi @DebkanchanSamadder, I'd be happy to have a look, but could you maybe provide a small demoproject that reproduces the issue? That might be of help to quickly isolate and fix it.

debkanchan commented 4 years ago

@DwayneCoussement I tweaked the example app a little bit so here it is:

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_geofence/geofence.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';

  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();

  double _lat, _long;

  @override
  void initState() {
    super.initState();
    initPlatformState();

// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
    var initializationSettingsAndroid =
    new AndroidInitializationSettings('app_icon');
    var initializationSettingsIOS = IOSInitializationSettings(
        onDidReceiveLocalNotification: null);
    var initializationSettings = InitializationSettings(
        initializationSettingsAndroid, initializationSettingsIOS);
    flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: null);

  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;
    Geofence.initialize();
    Geofence.startListening(GeolocationEvent.entry, (entry) {
      print(entry);
      scheduleNotification("Entry of a georegion", "Welcome to: ${entry.id}");
    });

    Geofence.startListening(GeolocationEvent.exit, (entry) {
      scheduleNotification("Exit of a georegion", "Byebye to: ${entry.id}");
    });

    setState(() {
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: ListView(children: <Widget>[
          Text('Running on: $_platformVersion\n'),
          Text('lat: $_lat, long: $_long'),
          RaisedButton(child: Text("Add region"), onPressed: () async {
            final Coordinate loc = await Geofence.getCurrentLocation();
            Geolocation location = Geolocation(latitude: loc.latitude, longitude: loc.longitude, radius: 10, id: "Kerkplein13");
            Geofence.addGeolocation(location, GeolocationEvent.entry).then((onValue) {
              print("great success");
              scheduleNotification("Georegion added", "Your geofence has been added!");
            }).catchError((onError) {
              print("great failure");
            });
          },),
          RaisedButton(child: Text("get user location"), onPressed: () {
              Geofence.getCurrentLocation().then((coordinate) {
                scheduleNotification("Got location", "great got latitude: ${coordinate.latitude} and longitude: ${coordinate.longitude}");
                setState(() {
                  _lat = coordinate.latitude;
                  _long = coordinate.longitude;
                });
              });
          })
        ],
        ),
      ),
    );
  }

  void scheduleNotification(String title, String subtitle) async
   {
    print(title + " " + subtitle);
    var androidPlatformChannelSpecifics = AndroidNotificationDetails(
          'your channel id', 'your channel name', 'your channel description',
          importance: Importance.Max, priority: Priority.High, ticker: 'ticker');
      var iOSPlatformChannelSpecifics = IOSNotificationDetails();
      var platformChannelSpecifics = NotificationDetails(
          androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
      await flutterLocalNotificationsPlugin.show(
          0, title, subtitle, platformChannelSpecifics,
          payload: 'item x');
  }

}

I was able to isolate 2 problems:

  1. Location accuracy is off. Even when I walk about 10 meters the location doesn't update. This can propose a serious issue for tight geofences.

  2. In the example above geofence is added at the current location. Now at first when I'd add the geofence, GeolocationEvent.entry would fire but suddenly it stopped working. At the same time regular geofencing also worked but stopped suddenly.

niypoo commented 4 years ago

I have same issue but when terminated app the listener not trigger but when app is open it's working ! and I noticed this issue in console

I GeofencerStateMachine: removeGeofences: removeRequest=RemoveGeofencingRequest[REMOVE_BY_PENDING_INTENT pendingIntent=PendingIntent[creatorPackage=com.google.android.gms], packageName=com.google.android.gms]

debkanchan commented 4 years ago

I have same issue but when terminated app the listener not trigger but when app is open it's working ! and I noticed this issue in console

I GeofencerStateMachine: removeGeofences: removeRequest=RemoveGeofencingRequest[REMOVE_BY_PENDING_INTENT pendingIntent=PendingIntent[creatorPackage=com.google.android.gms], packageName=com.google.android.gms]

is everything working when the app is open?

niypoo commented 4 years ago

I have same issue but when terminated app the listener not trigger but when app is open it's working ! and I noticed this issue in console I GeofencerStateMachine: removeGeofences: removeRequest=RemoveGeofencingRequest[REMOVE_BY_PENDING_INTENT pendingIntent=PendingIntent[creatorPackage=com.google.android.gms], packageName=com.google.android.gms]

is everything working when the app is open?

Ios working as prefect in open/terminated // test on simulator Android working not as ios from 10 attempts entry event trigger 2/3 executed on open app but when terminated nothing executing // test on emulator and physical device with mock location,

I want test in real world maybe it will different !

maksym-ostrovyj-ew commented 4 years ago

I have the same problem, but only the subscription to exit the geofence does not work. Getting into geofence works correctly

niypoo commented 4 years ago

I have same issue but when terminated app the listener not trigger but when app is open it's working ! and I noticed this issue in console I GeofencerStateMachine: removeGeofences: removeRequest=RemoveGeofencingRequest[REMOVE_BY_PENDING_INTENT pendingIntent=PendingIntent[creatorPackage=com.google.android.gms], packageName=com.google.android.gms]

is everything working when the app is open? did you notice in android ! entry event never fired, only exit event fired !

debkanchan commented 4 years ago

This issue has been inactive for a long time

debkanchan commented 4 years ago

@DwayneCoussement Any updates? Latest release certainly didn't fix the issue.

Luktm commented 4 years ago

@DwayneCoussement sir, I also facing the same problem here, Geofence.startListening won't trigger in Android Platform at all, but ios work perfectly. Please help!!

blaster92 commented 4 years ago

Hello, I have experienced the same problem: startListening method is not invoked on both Android simulator and physical device. Tried with Samsung Galaxy S8 and Moto G5. Current location is retrieved correctly, as well as requestPermission feature.

Thanks!

marwenbk commented 4 years ago

i also have the same problem , ! hep please

blaster92 commented 4 years ago

So after a while, digging into API documentations and related Android implementation of the plugin, I have understood that events are not triggered when geofence radius is too small for the accuracy level of GPS signal. In fact, by increasing the radius of the geofence, I was able to receive notifications of entrance and exit in/from the fence I have created. Specifically, when I was trying with radius equal to 1 or 10, it was not working, while if I increased it to 100, it was working perfectly.

Hope this could help!

prabhunath111 commented 4 years ago

Hope it will work for me also, let me check,If this one works, It'll be very useful for all of us who are facing this issue in the last few times.

Thanks and love to blaster92...:)

On Tue, Jun 30, 2020 at 3:02 PM blaster92 notifications@github.com wrote:

So after a while, digging into API documentations and related Android implementation of the plugin, I have understood that events are not triggered when geofence radius is too small for the accuracy level of GPS signal. In fact, by increasing the radius of the geofence, I was able to receive notifications of entrance and exit in/from the fence I have created. Specifically, when I was trying with radius equal to 1 or 10, it was not working, while if I increased it to 100, it was working perfectly.

Hope this could help!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/DwayneCoussement/flutter_geofence/issues/5#issuecomment-651679350, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK2CCF4WPJPX66SHYJYWKCTRZGWLVANCNFSM4KPGFO5Q .

debkanchan commented 4 years ago

Can anyone please check what's the minimum working radius?

debkanchan commented 4 years ago

I checked twice and even with a radius of 100m the geofence is still not working. Furthermore the getCurrentLocation seems to be very unreliable

blaster92 commented 4 years ago

I checked twice and even with a radius of 100m the geofence is still not working. Furthermore the getCurrentLocation seems to be very unreliable

I would say that using a function to verify that current position falls within a predefined geofence (circle or polygon) is a more reliable solution.

debkanchan commented 4 years ago

I checked twice and even with a radius of 100m the geofence is still not working. Furthermore the getCurrentLocation seems to be very unreliable

I would say that using a function to verify that current position falls within a predefined geofence (circle or polygon) is a more reliable solution.

At this point of time it looks like it indeed is the solution. But I have concern about battery life and performance and reliability on low end devices. That was the reason I wanted geofence because I thought it is now a mature solution which is more reliable than my vitamix code.

But looking at the current situation, will manually measuring haversine distance as a callback to a location service that runs even when app is killed be a good idea? of course it has a distance filter of 20m and interval of 5 sec

MahmoudEzzatAbdul-Rahman commented 4 years ago

Same with me, entry events are okay, exit events never fire .. even when increasing the radius to 100

aidooyaw1992 commented 4 years ago

@MahmoudEzzatAbdul-Rahman me too, entry fires but exit doesnt

rodrigonso commented 3 years ago

Hi all, I've been experiencing the same issue as most of you have.

From my perspective it seemed that it was very random when the events were triggered -- sometimes they would trigger exactly as they should, and some other times they just wouldn't trigger at all.

I've done some digging to understand why this was the case, and ended up finding this interesting post regarding iOS devices; however, we can assume the same/similar applies to android devices as well.

Basically, the precision of the location varies between 100-200 meters depending on the device's capabilities and what localization solutions it is using (i.e. GPS or GPS + Wi-Fi) simply put, if the device is connected to a Wi-Fi network, you can assume the minimum radius a geofence region can have is 100 meters. Otherwise it is recommended to stick with 200 meters as a safe bet.

Also, the post mentions that geofence events (at least on iOS) are not triggered immediately, rather after 20 seconds give or take to make sure you're not going in-and-out of the geofence region. In other words, it only triggers geofence events if the device is either moving away from the border (i.e. entering the region) and staying inside or if the device is moving toward the border (i.e exiting the region) and staying outside.

In a nutshell, it reiterates what @blaster92 was saying and adds one more constraint.

I haven't tested the plugin with this new knowledge, but I will try it as soon as possible and update you all.

You can read the whole thing in this link: https://developer.apple.com/forums/thread/94091

Also, if anyone got it to work regardless of minimum distance and the other constraints I've talked about above, please let me know!

rodrigonso commented 3 years ago

UPDATE

Hey everyone it's me again, coming with good news.

I've tested the plugin with the constraints I've outlined above and it works perfectly. For testing, I defined two different Georegions and set a radius of 200 meters for both. Drove around a little bit and got both entry and exit events for both regions. As I predicted, sometimes the events are triggered a little late, and sometimes they trigger pretty fast.

For those still experiencing this issue, I would suggest trying these suggestions out and see if it works.

I'll also submit a pull request to add those constraints to the documentation of this plugin so future users are aware of these constraints from the get-go.

Cheers :D

aashu5 commented 3 years ago

yeah, I am using this code in my app and also I am adding things in the manifest. I am not getting that what is the channel id, channel name and channel description, can you clear it how to generate all these?

Showing error Unresolved class GeofenceBroadcastReceiver And also unresolved class GeofencePlugin when I am adding receiver and services in manifest.

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

<application
    android:name="io.flutter.app.FlutterApplication"
    android:label="geofence"
    android:icon="@mipmap/ic_launcher">

    <activity
        android:name=".MainActivity"
        android:launchMode="singleTop"
        android:theme="@style/LaunchTheme"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

    <receiver android:name="com.example.geofence.GeofenceBroadcastReceiver"
        android:enabled="true"
        android:exported="true"/>
    <service android:name="com.example.geofence.GeofencePlugin"
        android:permission="android.permission.BIND_JOB_SERVICE"
        android:exported="true"/>
    <!-- Don't delete the meta-data below.
         This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
    <meta-data
        android:name="flutterEmbedding"
        android:value="2" />
</application>

Hey, is this library working to fetch geofence entry exit points?

sri-vathsa commented 2 years ago

Facing the same issue. I am getting notifications of entry to a geofence region but not getting any exit events.