Reputation: 1606
I am using the MvvmCross framework for cross device development. When I test my app in the Android emulator (I can't test it on a physical device yet) I get an Java.Lang.IllegalArgumentException exception when calling RequestLocationUpdates on the LocationManager. Also, I don't know whether it is relevant, but when I hover the mouse over the statement I get told that RequestLocationUpdates is an "Unknown Method". This happens whether the exception has occurred or not.
It seems to only happen the second time I call it in my application but the code that clears it down between uses looks like it should work
protected override void PlatformSpecificStart(MvxGeoLocationOptions options)
{
if (_locationManager != null)
throw new MvxException("You cannot start the MvxLocation service more than once");
_locationManager = (LocationManager)Context.GetSystemService(Context.LocationService);
var criteria = new Criteria() { Accuracy = options.EnableHighAccuracy ? Accuracy.Fine : Accuracy.Coarse };
var bestProvider = _locationManager.GetBestProvider(criteria, true);
_locationManager.RequestLocationUpdates(bestProvider, 5000, 2, this);
}
protected override void PlatformSpecificStop()
{
EnsureStopped();
}
private void EnsureStopped()
{
if (_locationManager != null)
{
_locationManager.RemoveUpdates(this);
_locationManager = null;
}
}
The class this is in inherits from Java.Lang.Object and I have verified that the PlatformSpecificStart and Stop and called at the appropriate times (i.e. the Stop is definitely called before the second Start). Can anyone tell me what is going wrong?
Upvotes: 1
Views: 791
Reputation: 66882
I've added a lesson in the tutorial that shows the IMvxGeoLocationWatcher
interface being used.
See the sample in https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20Tutorial/Tutorial/Tutorial.Core/ViewModels/Lessons/LocationViewModel.cs with code like:
private void DoStartStop()
{
if (!IsStarted)
{
_watcher.Start(new MvxGeoLocationOptions() { EnableHighAccuracy = true }, OnNewLocation, OnError);
}
else
{
_watcher.Stop();
}
IsStarted = !IsStarted;
}
private void OnError(MvxLocationError error)
{
// TODO - shuold handle the error better than this really!
LastError = error.Code.ToString();
}
private void OnNewLocation(MvxGeoLocation location)
{
if (location != null && location.Coordinates != null)
{
Lat = location.Coordinates.Latitude;
Lng = location.Coordinates.Longitude;
}
}
This seems to work OK on:
I haven't yet written the code for WinRT...
One thing that might be causing your errors is if you try to Dispose() the IMvxGeoLocationWatcher
instance - doing this might lead to unpredicatable results.
When dealing with GPS on WM6, iPhone, Bada, WP7 and Android for RunSat/Navmi (http://www.navmi.com) I've frequently encountered issues where the native platforms can be quite 'unstable'/'unpredictable' when the app starts/stops multiple location listeners - and I think this did influence the way I designed the IMvxGeoLocationWatcher
functionality. In general, if your app uses IMvxGeoLocationWatcher
then I think it's best to wrap the access to the location in some kind of singleton accessed through an interface - doing this will allow you to have much easier control on the location functionality, rather than having multiple clients all individually trying to start/stop the location managers.
If you find the functionality of IMvxGeoLocationWatcher
isn't what you are looking for, then by all means create your own interface and your own platform dependent implementations - they can be easily injected within each native Setup class.
For example, one thing you might like to try is an interface using the Mono mobile extensions which are available for Location (as well as for Contacts and for some a growing number of other features too)
Upvotes: 1