Skip to content

Instantly share code, notes, and snippets.

@thongdoan
Last active August 29, 2015 14:28
Show Gist options
  • Save thongdoan/a97b44710566ff613d6f to your computer and use it in GitHub Desktop.
Save thongdoan/a97b44710566ff613d6f to your computer and use it in GitHub Desktop.
using System;
using System.Threading;
using Android.Content;
using Android.Locations;
using Android.OS;
using Cirrious.CrossCore;
using Cirrious.CrossCore.Droid;
using Cirrious.CrossCore.Droid.Platform;
using Cirrious.CrossCore.Exceptions;
using Cirrious.CrossCore.Platform;
using Cirrious.MvvmCross.Plugins.Location;
using Cirrious.MvvmCross.Plugins.Location.Droid;
namespace YourNamespace
{
//Fix MvxAndroidLocationWatcher not work when app start with service is turn off
public sealed class AndroidLocationWatcher : MvxLocationWatcher, IMvxLocationReceiver
{
private Context _context;
private LocationManager _locationManager;
private MvxLocationListener _locationListener;
private string _bestProvider;
//
// Properties
//
private Context Context {
get {
if (this._context == null) {
this._context = Mvx.Resolve<IMvxAndroidGlobals> ().ApplicationContext;
}
return this._context;
}
}
public override MvxGeoLocation CurrentLocation {
get {
if (_locationManager == null || _bestProvider == null) {
throw new MvxException ("Location Manager not started");
}
Android.Locations.Location lastKnownLocation = _locationManager.GetLastKnownLocation (_bestProvider);
if (lastKnownLocation == null) {
return null;
}
return AndroidLocationWatcher.CreateLocation (lastKnownLocation);
}
}
//
// Constructors
//
public AndroidLocationWatcher ()
{
this.EnsureStopped ();
this._locationListener = new MvxLocationListener (this);
}
//
// Static Methods
//
private static MvxGeoLocation CreateLocation (Android.Locations.Location androidLocation)
{
MvxGeoLocation mvxGeoLocation = new MvxGeoLocation {
Timestamp = androidLocation.Time.FromMillisecondsUnixTimeToUtc ()
};
MvxCoordinates coordinates = mvxGeoLocation.Coordinates;
if (androidLocation.HasAltitude) {
coordinates.Altitude = new double? (androidLocation.Altitude);
}
if (androidLocation.HasBearing) {
coordinates.Heading = new double? ((double)androidLocation.Bearing);
}
coordinates.Latitude = androidLocation.Latitude;
coordinates.Longitude = androidLocation.Longitude;
if (androidLocation.HasSpeed) {
coordinates.Speed = new double? ((double)androidLocation.Speed);
}
if (androidLocation.HasAccuracy) {
coordinates.Accuracy = new double? ((double)androidLocation.Accuracy);
}
return mvxGeoLocation;
}
//
// Methods
//
private void EnsureStopped ()
{
if (_locationManager != null) {
_locationManager.RemoveUpdates (this._locationListener);
_locationManager = null;
_bestProvider = null;
}
}
public void OnLocationChanged (Android.Locations.Location androidLocation)
{
if (androidLocation == null) {
MvxTrace.Trace ("Android: Null location seen");
return;
}
if (androidLocation.Latitude == double.MaxValue
|| androidLocation.Longitude == double.MaxValue) {
MvxTrace.Trace ("Android: Invalid location seen");
return;
}
MvxGeoLocation location;
try {
location = CreateLocation (androidLocation);
} catch (ThreadAbortException) {
throw;
} catch (Exception exception) {
MvxTrace.Trace ("Android: Exception seen in converting location " + exception.ToLongString ());
return;
}
SendLocation (location);
}
public void OnProviderDisabled (string provider)
{
base.SendError (MvxLocationErrorCode.ServiceUnavailable);
}
public void OnProviderEnabled (string provider)
{
}
public void OnStatusChanged (string provider, Availability status, Bundle extras)
{
switch (status) {
case Availability.OutOfService:
base.SendError (MvxLocationErrorCode.ServiceUnavailable);
break;
case Availability.TemporarilyUnavailable:
base.SendError (MvxLocationErrorCode.PositionUnavailable);
return;
case Availability.Available:
return;
}
}
protected override void PlatformSpecificStart (MvxLocationOptions options)
{
if (_locationManager != null) {
throw new MvxException ("You cannot start the MvxLocation service more than once");
}
_locationManager = (LocationManager)this.Context.GetSystemService ("location");
if (_locationManager == null) {
MvxTrace.Warning ("Location Service Manager unavailable - returned null", new object[0]);
base.SendError (MvxLocationErrorCode.ServiceUnavailable);
return;
}
var criteria = new Criteria {
Accuracy = (options.Accuracy == MvxLocationAccuracy.Fine) ? Accuracy.Fine : Accuracy.Coarse
};
_bestProvider = _locationManager.GetBestProvider (criteria, true);
//TH added to fix MvxAndroidLocationProvider
if (_bestProvider == LocationManager.PassiveProvider) {
var realBestProvider = _locationManager.GetBestProvider (criteria, false);
if (realBestProvider != LocationManager.PassiveProvider)
_bestProvider = realBestProvider;
}
if (_bestProvider == null) {
MvxTrace.Warning ("Location Service Provider unavailable - returned null", new object[0]);
base.SendError (MvxLocationErrorCode.ServiceUnavailable);
return;
}
_locationManager.RequestLocationUpdates (_bestProvider, (long)options.TimeBetweenUpdates.TotalMilliseconds, (float)options.MovementThresholdInM, this._locationListener);
}
protected override void PlatformSpecificStop ()
{
this.EnsureStopped ();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment