CrossGeeks / GeofencePlugin

Geofence Plugin for Xamarin iOS and Android
MIT License
48 stars 22 forks source link

System.InvalidCastException: Specified cast is not valid. #4

Open smrkamran opened 5 years ago

smrkamran commented 5 years ago

Getting this exceptions when calling StartMonitoring method in AppConstructor

public App () { InitializeComponent(); MainPage = new NavigationPage(new MainPage()); CrossGeofence.Current.StartMonitoring(new GeofenceCircularRegion("asdsadasdasdas", 31.475085, 74.305833, 200.0) { NotifyOnStay = true, StayedInThresholdDuration = TimeSpan.FromMinutes(5) }); }

napoleonjones commented 5 years ago

It's all good man. I don't have access to my code right now but if I remember correctly, I wrote made the call from a separate service. I have another background service that gets locations within a certain radius. I then add those locations as geofence regions.

smrkamran commented 5 years ago

ok bro thanks..

napoleonjones commented 5 years ago

I just started working with the plug-in last night, but I just followed everything in the readme file. It built and ran with no errors.

kberawala commented 5 years ago

image

I get this randomly.

aaronwhite42 commented 5 years ago

I too get this InvalidCastException.

As a work-around, I put the following line in MainActivity.cs in my project:

ActivityCompat.RequestPermissions(this, new[] { Manifest.Permission.AccessFineLocation }, 101);

The original line lifted from GeofenceImplementation attempts to cast the 'Application.Context' to an activity, which when using the recommended GeofenceAppStarter class, causes the InvalidCastException:

ActivityCompat.RequestPermissions((Activity) Application.Context, new[] { Manifest.Permission.AccessFineLocation }, REQUEST_PERMISSIONS_REQUEST_CODE);

93asad commented 5 years ago

I think I've found the root cause of it on iOS.

Within the constructor the GeofenceImplementation class for iOS performs a foreach on items returned by CLLocationManager.MonitoredRegions. It blindly tries to cast each item to CLCircularRegion assuming that all the items will either be CLRegion or CLCircularRegion, which is NOT true. According to the Apple docs CLLocationManager.MonitoredRegions returns a Set of CLRegion. This means that it can have ClBeaconRegion as well if you are monitoring beacon regions as well. Therefore if ClBeaconRegion exists in the items, the blind cast to CLCircularRegion will fail thereby throwing Invalid cast exception. Following is the code snippet from the source code of the project:

`var monitoredRegions = locationManager.MonitoredRegions;

          foreach (CLCircularRegion region in monitoredRegions)
          {
              //If not on regions remove on startup since that region was set not persistent
              if (!Regions.ContainsKey(region.Identifier))
              {
                  locationManager.StopMonitoring(region);
              }
              else
              {
                  locationManager.RequestState(region);
              }

          }`

Since this plugin only cares about Geofences, probably it is a good idea to filter out all the CLCircularRegions before performing a foreach:

`var monitoredRegions = locationManager.MonitoredRegions.Where (r => r is CLCircularRegion);

          foreach (CLCircularRegion region in monitoredRegions)
          {
              //If not on regions remove on startup since that region was set not persistent
              if (!Regions.ContainsKey(region.Identifier))
              {
                  locationManager.StopMonitoring(region);
              }
              else
              {
                  locationManager.RequestState(region);
              }

          }` 
nielscup commented 4 years ago

I had this same issue and it was caused by the app not having location permissions. So make sure your app has Location permissions. You can use the CrossPermissions plugin for that. CrossPermissions.Current.CheckPermissionStatusAsync As a workaround you can manually give the app location permissions via app settings to see if this causes the error.