jamesmontemagno / GeolocatorPlugin

Geolocation plugin for Xamarin and Windows
MIT License
294 stars 158 forks source link

PositionChanged event does not fire in PCL iOS project, works for Android #180

Open calbert52 opened 7 years ago

calbert52 commented 7 years ago

If you are creating an issue for a BUG please fill out this information. If you are asking a question or requesting a feature you can delete the sections below.

Failure to fill out this information will result in this issue being closed. If you post a full stack trace in a bug it will be closed, please post it to http://gist.github.com and then post the link here.

Bug Information

Version Number of Plugin: 4.1.2 Device Tested On: iPhone 7+ (11.0.3) Simulator Tested On: VS 2017 iPhone 7 Version of VS: Microsoft Visual Studio Enterprise 2017 Version 15.4.2 Version of Xamarin: 4.7.10.33 (70936af)

Versions of other things you are using: VisualStudio.Mac 1.0 Mac Extension for Visual Studio Xamarin 4.7.10.33 (70936af) Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android. Xamarin.Android SDK 8.0.2.1 (HEAD/c2a33d8ea) Xamarin.Android Reference Assemblies and MSBuild support. Xamarin.iOS and Xamarin.Mac SDK 11.2.1.0 (12e80e0) Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

NuGet packages:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Acr.DeviceInfo" version="5.0.5" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Acr.UserDialogs" version="6.4.1" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="C1.CollectionView" version="2.3.20172.189" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="C1.Xamarin.Forms.Calendar" version="2.3.20172.189" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="C1.Xamarin.Forms.Chart" version="2.3.20172.189" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="C1.Xamarin.Forms.Core" version="2.3.20172.189" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="C1.Xamarin.Forms.Grid" version="2.3.20172.189" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="C1.Xamarin.Forms.Input" version="2.3.20172.189" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Microsoft.NETCore.Platforms" version="2.0.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="NETStandard.Library" version="2.0.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Newtonsoft.Json" version="10.0.3" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Plugin.Permissions" version="2.1.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Rx-Core" version="2.2.5" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Rx-Interfaces" version="2.2.5" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Rx-Linq" version="2.2.5" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Rx-Main" version="2.2.5" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="sqlite-net-pcl" version="1.4.118" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="SQLitePCLRaw.bundle_green" version="1.1.8" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Collections" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.ComponentModel" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Diagnostics.Contracts" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Dynamic.Runtime" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Globalization" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.IO" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Linq" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Linq.Expressions" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Net.Primitives" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.ObjectModel" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Reactive" version="3.1.1" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Reactive.Core" version="3.1.1" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Reactive.Linq" version="3.1.1" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Reactive.PlatformServices" version="3.1.1" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Reflection" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Runtime" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Runtime.InteropServices.WindowsRuntime" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Text.Encoding" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Threading" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Threading.Tasks" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="System.Xml.XDocument" version="4.3.0" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Xam.Plugin.Connectivity" version="3.0.3" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Xam.Plugin.Geolocator" version="4.1.2" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Xam.Plugins.Settings" version="3.1.1" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Xamarin.Build.Download" version="0.4.7" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="Xamarin.Forms" version="2.4.0.38779" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="ZXing.Net.Mobile" version="2.1.47" targetFramework="portable45-net45+win8+wp8+wpa81" />
  <package id="ZXing.Net.Mobile.Forms" version="2.1.47" targetFramework="portable45-net45+win8+wp8+wpa81" />
</packages>

Steps to reproduce the Behavior

Build for iOS loc.StartListeningAsync(...)

Expected Behavior

Listen for changes in location and fire event PositionChanged.

Actual Behavior

Listens for changes in location but never fires the PositionChanged event

Code snippet

public static IGeolocator loc = CrossGeolocator.Current;
loc.DesiredAccuracy = 30;
loc.PositionChanged += async (sender, args) =>
                {
                    if (!locIsBusy)
                    {
                        locIsBusy = true;
                        try
                        {
                            Models.LocationAddress address = null;

                            // Do not do this when the app sleeps, it will use too much battery.
                            if (App.ApplicationState != Enums.ApplicationStateEnum.OnSleep)
                            {
                                var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
                                if (status == PermissionStatus.Granted)
                                {
                                    if (App.Setting != null && App.Setting.UseGPS)
                                    {
                                        Position position = args.Position;// await CrossGeolocator.Current.GetPositionAsync(10000);
                                        if (position != null)
                                        {
                                            position.Latitude = Double.Parse(position.Latitude.TruncateDecimalDigitsToString(7));
                                            position.Longitude = Double.Parse(position.Longitude.TruncateDecimalDigitsToString(7));
                                            App.myPosition = position;
                                            try
                                            {
                                                address = await PerformReverseGeocode(position);
                                            }
                                            catch { address = null; }
                                            App.myAddress = address;
                                        }
                                        else
                                        {
                                            App.myPosition = null;
                                            App.myAddress = null;
                                        }
                                    }
                                    else
                                    {
                                        App.myPosition = null;
                                        App.myAddress = null;
                                    }
                                }
                                else
                                {
                                    App.myPosition = null;
                                    App.myAddress = null;
                                    if (App.Setting != null && App.Setting.UseGPS)
                                    {
                                        // Code here to tell user that they need to allow the use of Location services.
                                    }
                                }
                            }
                        }
                        catch (Exception ex) { LogException(ex); }
                        finally
                        {
                            locIsBusy = false;
                        }
                    }
                };

                loc.PositionError += (sender, args) =>
                {
                    App.AddLog("GeoLocation error: " + args.Error.ToString());
                };
await App.loc.StartListeningAsync(TimeSpan.FromSeconds(5), 10, true, new Plugin.Geolocator.Abstractions.ListenerSettings
                            {
                                ActivityType = Plugin.Geolocator.Abstractions.ActivityType.AutomotiveNavigation,
                                AllowBackgroundUpdates = true,
                                DeferLocationUpdates = true,
                                DeferralDistanceMeters = 1,
                                DeferralTime = TimeSpan.FromSeconds(1),
                                ListenForSignificantChanges = true,
                                PauseLocationUpdatesAutomatically = false
                            });

Screenshotst

kingnguyen93 commented 7 years ago

ListenForSignificantChanges = false

calbert52 commented 7 years ago

ListenForSignificantChanges = false, did not correct the issue.

kingnguyen93 commented 7 years ago

On IOS you must meet two condition DeferralTime and DeferralDistanceMeters, then event trigger. And remember to update to at least 4.1.2 or 4.1.2.167. Geolocator on mine still work good on IOS.

prashantvc commented 6 years ago

@calbert52 How are you testing your app for location changes? Could you elaborate the issue? Did @kingnguyen1993 explanation help you?

calbert52 commented 6 years ago

No, @kingnguyen1993 explanation did not resolve my issue. I could not spend any more time on trying to get it to work using a lamda event handler on PositionChanged to update my current location. Now testing for location change once every 20 seconds using GetPostionAsync() on a thread.

My code snippet above from Nov 7th should show how I was coding it. My testing was done on a real iOS device, testing in the Xamarin iOS simulator remoted to the PC produced faults. Testing on the iOS simulator on the mac did not produce any faults, but the PositionChanged event never fired.

oloap86 commented 6 years ago

Hi guys, i'had the same problem on ios in background mode and i solved with a parallel trick under the ios project. I create a CLLocationManager under ios project witch start listening position changes (StartMonitoringSignificantLocationChanges) only when the app enter in background and this wake up the plugin calling my location changes under the pcl.

You can my code in attachment

IOS_BG_POSITION.txt