Last active
August 29, 2015 14:28
-
-
Save thongdoan/a97b44710566ff613d6f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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