2016-08-15 63 views
0

我想实现一个自定义活动,它将在Xamarin c#中初始化融合位置服务,这样我就可以在需要融合位置时重用此活动。我遇到的问题是地图在位置服务之前加载。这样,由于位置仍然为空,我无法对相机进行动画处理以放大用户的位置。Android - Xamarin - 融合位置

这里是自定义活动:

using System; 
using Android.App; 
using Android.Gms.Common; 
using Android.Gms.Common.Apis; 
using Android.Gms.Maps.Model; 
using Android.Locations; 
using Android.OS; 
using Android.Gms.Location; 
using Android.Widget; 

namespace Maps.Droid.LocationService { 
    public class LocationTrackerActivity : Activity, GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener, Android.Gms.Location.ILocationListener { 
     // Static Fields 
     public static long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 5 meters 
     public static long MIN_TIME_BW_UPDATES = 1000 * 10; // 10 seconds 

     private Location currentLocation; 
     private Activity activity; 
     private bool hasGooglePlayServices; 
     private GoogleApiClient mGoogleApiClient; 
     private LocationRequest mLocationRequest; 
     private bool locationAvailable = false; 

     protected override void OnCreate(Bundle savedInstanceState) { 
      base.OnCreate(savedInstanceState); 

      this.activity = this; 

      hasGooglePlayServices = checkPlayServices(); 

      if (hasGooglePlayServices) { 
       initFusedLocation(); 
      } else { 
       initAndroidLocation(); 
      } 
     } 

     private void initFusedLocation() { 
      mLocationRequest = new LocationRequest(); 
      mLocationRequest.SetInterval(LocationTrackerActivity.MIN_TIME_BW_UPDATES); 
      mLocationRequest.SetFastestInterval(LocationTrackerActivity.MIN_TIME_BW_UPDATES/2); 
      mLocationRequest.SetSmallestDisplacement(LocationTrackerActivity.MIN_DISTANCE_CHANGE_FOR_UPDATES); 
      mLocationRequest.SetPriority(LocationRequest.PriorityHighAccuracy); 

      mGoogleApiClient = new GoogleApiClient.Builder(Application.Context) 
       .AddConnectionCallbacks(this) 
       .AddOnConnectionFailedListener(this) 
       .AddApi(LocationServices.API) 
       .Build(); 
     } 

     protected override void OnResume() { 
      base.OnResume(); 
      if (mGoogleApiClient.IsConnected) { 
       LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
      } 
     } 

     protected override void OnPause() { 
      base.OnPause(); 
      // Stop location updates to save battery, but don't disconnect the GoogleApiClient object. 
      if (mGoogleApiClient.IsConnected) { 
       LocationServices.FusedLocationApi.RemoveLocationUpdates(mGoogleApiClient, this); 
      } 
     } 

     protected override void OnStart() { 
      base.OnStart(); 
      mGoogleApiClient.Connect(); 
     } 

     protected override void OnStop() { 
      base.OnStop(); 
      // only stop if it's connected, otherwise we crash 
      if (mGoogleApiClient != null) { 
       mGoogleApiClient.Disconnect(); 
      } 
     } 

     private void initAndroidLocation() { 

     } 

     private bool checkPlayServices() { 
      GoogleApiAvailability apiAvailability = GoogleApiAvailability.Instance; 
      int resultCode = apiAvailability.IsGooglePlayServicesAvailable(activity); 
      if (resultCode != ConnectionResult.Success) { 
       // In case we want to tell the user to install or update Google Play Services 
       //if (apiAvailability.IsUserResolvableError(resultCode)) { 
       // apiAvailability.GetErrorDialog(activity, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST).Show(); 
       //} else { 
       // Toast.MakeText(activity, "This device is not supported", ToastLength.Long).Show(); 
       //} 
       return false; 
      } 
      return true; // has google play services installed 
     } 

     public double getLatitude() { 
      return currentLocation == null ? 0.0 : currentLocation.Latitude; 
     } 

     public double getLongitude() { 
      return currentLocation == null ? 0.0 : currentLocation.Longitude; 
     } 

     public bool canGetLocation() { 
      return locationAvailable; 
     } 

     public LatLng getLatLng() { 
      return new LatLng(currentLocation.Latitude, currentLocation.Longitude); 
     } 

     public void OnConnected(Bundle connectionHint) { 
      // Get last known recent location. If the user launches the activity, 
      // moves to a new location, and then changes the device orientation, the original location 
      // is displayed as the activity is re-created. 
      if (currentLocation == null && mGoogleApiClient.IsConnected) { 
       currentLocation = LocationServices.FusedLocationApi.GetLastLocation(mGoogleApiClient); 
      } 
      Console.WriteLine("location is about to be set to true"); 

      locationAvailable = true; 

      LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
     } 

     public void OnConnectionSuspended(int cause) { 
      // GoogleApiClient will automatically attempt to restore the connection. 
      // Applications should disable UI components that require the service, and wait for a call to onConnected(Bundle) to re-enable them 

      if (cause == GoogleApiClient.ConnectionCallbacks.CauseServiceDisconnected) { 
       Toast.MakeText(activity, "Location Services disconnected. Please re-connect.", ToastLength.Long).Show(); 
      } else if (cause == GoogleApiClient.ConnectionCallbacks.CauseNetworkLost) { 
       Toast.MakeText(activity, "Network lost. Please re-connect.", ToastLength.Long).Show(); 
      } 
     } 

     public void OnConnectionFailed(ConnectionResult result) { 
      Console.WriteLine("Connection failed: " + result.ToString()); 
     } 

     public void OnLocationChanged(Location location) { 
      currentLocation = location; 
     } 
    } 
} 

这里是继承自定义类的类:

using Android.App; 
using Android.OS; 
using Maps.Droid.LocationService; 

namespace Maps.Droid { 
    [Activity(Label = "Map Activity")] 
    public class MapActivity : LocationTrackerActivity { 
     // Properties 

     protected override void OnCreate(Bundle savedInstanceState) { 
      base.OnCreate(savedInstanceState); 
      SetContentView(Resource.Layout.map_activity); 

      var mapFrag = new MapViewFragment(); 
      var ft = FragmentManager.BeginTransaction(); 
      ft.Add(Resource.Id.map_container, mapFrag); 
      ft.Commit(); 
     } 
    } 
} 

这里是继承的活动片段:

using System; 
using Android.App; 
using Android.OS; 
using Android.Views; 
using Android.Gms.Maps; 

namespace Maps.Droid { 
    public class MapViewFragment : Fragment, IOnMapReadyCallback { 
     // private Activity activity; 
     private GoogleMap map; 
     private MapActivity parent; 

     public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
      View view = inflater.Inflate(Resource.Layout.map_fragment, null); 

      parent = ((MapActivity)Activity); 

      MapFragment frag = this.FragmentManager.FindFragmentById<MapFragment>(Resource.Id.map); 
      frag.GetMapAsync(this); 

      return view; 
     } 

     public void OnMapReady(GoogleMap googleMap) { 
      if (googleMap != null) { 
       map = googleMap; 
       var zoomVariance = 0.2; 
       var defaultZoom = 16f; 
       var currentZoomLevel = map.CameraPosition.Zoom; 

       map.MapType = GoogleMap.MapTypeNormal; 
       map.MyLocationEnabled = true; 

       map.CameraChange += delegate (object sender, GoogleMap.CameraChangeEventArgs e) { 
        if (Math.Abs(e.Position.Zoom - currentZoomLevel) < zoomVariance) { 
         return; 
        } 

        currentZoomLevel = e.Position.Zoom; 
        Console.WriteLine("Zooming " + currentZoomLevel); 
       }; 

       map.UiSettings.ZoomControlsEnabled = true; 
       map.UiSettings.CompassEnabled = true; 
       map.UiSettings.SetAllGesturesEnabled(true); // Zoom, Tilt, Scroll, Rotate 

       if (parent.canGetLocation()) { 
        // ***** PROBLEM HERE ******* canGetLocation is set to true just afterwards. 
        map.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(parent.getLatLng(), defaultZoom)); // Mosaic coordinates 
       } 
      } 
     } 
    } 
} 

我正在考虑实施回调LocationTrackerActivity。因此,当位置服务变为可用时,MapActivity类将能够在该自定义回调中加载MapViewFragment。这样位置服务将在地图之前加载。因此,这部分代码将始终执行:

if (parent.canGetLocation()) { 
    // ***** PROBLEM HERE ******* canGetLocation is set to true just afterwards. 
    map.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(parent.getLatLng(), defaultZoom)); // Mosaic coordinates 
} 

但是我不知道如何自定义回调。也许有更好的解决方案来解决这个问题?

回答

0

问题可能是因为OnConnected方法。这是Xamarin中FusedLocationProvider的OnConnected方法。你可以看看它。

public async void OnConnected(Bundle bundle) 
    { 
     Location location = LocationServices.FusedLocationApi.GetLastLocation(apiClient); 

     if (location != null) 
     { 
      latitude = location.Latitude; 
      longitude = location.Longitude; 

      locRequest.SetPriority(100); 
      locRequest.SetFastestInterval(500); 
      locRequest.SetInterval(1000); 

      await LocationServices.FusedLocationApi.RequestLocationUpdates(apiClient, locRequest, this); 
     } 
    } 

当它连接,我设置经度和纬度值。然后在我的onMapReady方法中,我用这些经度和纬度变量创建一个新的LatLng变量。

void IOnMapReadyCallback.OnMapReady(GoogleMap myMap) 
    { 
     this.myMap = myMap; 
     myMarker = new MarkerOptions(); 
     locCoordinates = new LatLng(latitude, longitude); 

     myMap.MapType = GoogleMap.MapTypeNormal; 
     myMap.UiSettings.ZoomControlsEnabled = true; 
     myMap.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(locCoordinates, 10)); 
    } 

UPDATE:

我设法找到一个解决方案。如果用户有谷歌播放服务,然后使用FusedLocation服务,如果用户没有,那么我们使用Android定位服务。然后,我们只需要与类型LocationTracker的一个对象交互,一切都通过这个接口完成:

namespace Maps.Droid.LocationService { 
    public interface LocationInterface { 
     void startLocationServices(); 
     void stopLocationServices(); 
     void pauseLocationServices(); 
     void resumeLocationServices(); 
     double getLatitude(); 
     double getLongitude(); 
     bool canGetLocation(); 
    } 
} 

using System; 
using Android.App; 
using Android.Gms.Location; 
using Android.Gms.Common.Apis; 
using Android.OS; 
using Android.Gms.Maps.Model; 
using Android.Widget; 
using Android.Locations; 
using Android.Gms.Common; 
using Android.Gms.Maps; 

namespace Maps.Droid.LocationService { 
    public class FusedLocation : Java.Lang.Object, GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener, Android.Gms.Location.ILocationListener { 
     private Activity activity; 
     private GoogleApiClient mGoogleApiClient; 
     private LocationRequest mLocationRequest; 
     private Location currentLocation; 
     private bool locationAvailable = false; 
     private GoogleMap map; 

     public FusedLocation(Activity activity) { 
      this.activity = activity; 

      mLocationRequest = new LocationRequest(); 
      mLocationRequest.SetInterval(LocationTracker.MIN_TIME_BW_UPDATES); 
      mLocationRequest.SetFastestInterval(LocationTracker.MIN_TIME_BW_UPDATES/2); 
      mLocationRequest.SetSmallestDisplacement(LocationTracker.MIN_DISTANCE_CHANGE_FOR_UPDATES); 
      mLocationRequest.SetPriority(LocationRequest.PriorityHighAccuracy); 

      mGoogleApiClient = new GoogleApiClient.Builder(Application.Context) 
       .AddConnectionCallbacks(this) 
       .AddOnConnectionFailedListener(this) 
       .AddApi(LocationServices.API) 
       .Build(); 
     } 

     public Location getCurrentLocation() { 
      return currentLocation; 
     } 

     public void setMap(GoogleMap map) { 
      this.map = map; 
     } 

     public double getLatitude() { 
      return currentLocation.Latitude; 
     } 

     public double getLongitude() { 
      return currentLocation.Longitude; 
     } 

     public void OnResume() { 
      if (mGoogleApiClient.IsConnected) { 
       LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
      } 
     } 
     public void OnPause() { 
      // Stop location updates to save battery, but don't disconnect the GoogleApiClient object. 
      if (mGoogleApiClient.IsConnected) { 
       LocationServices.FusedLocationApi.RemoveLocationUpdates(mGoogleApiClient, this); 
      } 
     } 

     public void OnStart() { 
      mGoogleApiClient?.Connect(); 
     } 

     public void OnStop() { 
      // only stop if it's connected, otherwise we crash 
      if (mGoogleApiClient.IsConnected) { 
       mGoogleApiClient?.Disconnect(); 
      } 
     } 

     public LatLng getLatLng() { 
      return new LatLng(currentLocation.Latitude, currentLocation.Longitude); 

     } 
     public bool canGetLocation() { 
      return locationAvailable && currentLocation != null; 
     } 

     public void OnConnected(Bundle connectionHint) { 
      // Get last known recent location. If the user launches the activity, 
      // moves to a new location, and then changes the device orientation, the original location 
      // is displayed as the activity is re-created. 
      currentLocation = LocationServices.FusedLocationApi.GetLastLocation(mGoogleApiClient); 

      if (currentLocation != null) { 
       locationAvailable = true; 
       LocationServices.FusedLocationApi.RequestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 

       if (map != null) { 
        map.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(getLatLng(), LocationTracker.DEFAULT_ZOOM)); 
       } 
      } 
     } 

     public void OnConnectionSuspended(int cause) { 
      // GoogleApiClient will automatically attempt to restore the connection. 
      // Applications should disable UI components that require the service, and wait for a call to onConnected(Bundle) to re-enable them 
      if (cause == GoogleApiClient.ConnectionCallbacks.CauseServiceDisconnected) { 
       Toast.MakeText(activity, "Location Services disconnected. Please re-connect.", ToastLength.Long).Show(); 
      } else if (cause == GoogleApiClient.ConnectionCallbacks.CauseNetworkLost) { 
       Toast.MakeText(activity, "Network lost. Please re-connect.", ToastLength.Long).Show(); 
      } 
     } 

     public void OnLocationChanged(Location location) { 
      currentLocation = location; 
     } 

     public void OnConnectionFailed(ConnectionResult result) { 
      Console.WriteLine("Connection failed: " + result.ToString()); 
     } 
    } 
} 

using System; 
using Android.OS; 
using Android.Locations; 
using Android.Runtime; 
using Android.App; 
using Android.Content; 
using Android.Widget; 
using Android.Gms.Maps.Model; 
using Java.Util.Concurrent; 

namespace Maps.Droid.LocationService { 
    public class AndroidLocation : Java.Lang.Object, ILocationListener { 
     // Properties 
     private LocationManager locMgr; 
     private Activity activity; 
     private Location locationGPS, locationNetwork/*, locationPassive*/, currentLocation; 
     private bool locationAvailable = false; 
     private Android.Gms.Maps.GoogleMap map; 

     // UNCOMMNET 
     // private bool isPassiveEnabled = false; // Gets location from other apps that uses Location Services 

     // Initializer method (Constructor). Call this method onCreate 
     public AndroidLocation(Activity activity) { 
      this.activity = activity; 
      getLocation(); 
     } 

     public Location getCurrentLocation() { 
      return currentLocation; 
     } 

     public void setMap(Android.Gms.Maps.GoogleMap map) { 
      this.map = map; 
     } 

     private Location getLocation() { 
      // Use Standard Android Location Service Provider 
      try { 
       locMgr = activity.GetSystemService(Context.LocationService) as LocationManager; 

       bool isGPSEnabled = locMgr.IsProviderEnabled(LocationManager.GpsProvider); 

       // Varying precision, Less power consuming. Combination of WiFi and Cellular data 
       bool isNetworkEnabled = locMgr.IsProviderEnabled(LocationManager.NetworkProvider); 

       // UNCOMMENT 
       // bool isPassiveEnabled = locMgr.IsProviderEnabled(LocationManager.GpsProvider); 

       // UNCOMMNET 
       //if (isPassiveEnabled) { 
       // locMgr.RequestLocationUpdates(LocationManager.PassiveProvider, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
       // locationPassive = locMgr.GetLastKnownLocation(LocationManager.PassiveProvider); 
       //} 

       if (isGPSEnabled) { 
        locMgr.RequestLocationUpdates(LocationManager.GpsProvider, LocationTracker.MIN_TIME_BW_UPDATES, LocationTracker.MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        locationGPS = locMgr?.GetLastKnownLocation(LocationManager.GpsProvider); 
       } 

       if (isNetworkEnabled) { 
        locMgr.RequestLocationUpdates(LocationManager.NetworkProvider, LocationTracker.MIN_TIME_BW_UPDATES, LocationTracker.MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        locationNetwork = locMgr?.GetLastKnownLocation(LocationManager.NetworkProvider); 
       } 

       // UNCOMMENT - Method must be implement if PassiveLocation is to be used 
       // currentLocation = getBestLocation(locationGPS, locationNetwork, locationPassive); 

       currentLocation = getBestLocation(locationNetwork, locationGPS); 

       if (currentLocation != null) { 
        locationAvailable = true; 
        if (map != null) { 
         map.AnimateCamera(Android.Gms.Maps.CameraUpdateFactory.NewLatLngZoom(getLatLng(), LocationTracker.DEFAULT_ZOOM)); 
        } 
       } 
      } catch (Exception e) { 
       Console.WriteLine("ERROR: getLocation() " + e.ToString()); 
      } 

      return currentLocation; 
     } 

     // Determines the most recent and/or most accurate location 
     private Location getBestLocation(Location loc1, Location loc2) { 
      if (loc1 == null || loc2 == null) { 
       return loc1 ?? loc2; // If either location is null then return the not null location 
      } 

      long time1 = TimeUnit.Milliseconds.ToSeconds(loc1.Time); 
      long time2 = TimeUnit.Milliseconds.ToSeconds(loc2.Time); 

      long twiceUpdate = (LocationTracker.MIN_TIME_BW_UPDATES/1000) * 2; 
      if (Math.Abs(time1 - time2) > twiceUpdate) { // If location times are more than twiceUpdate apart 
       if (time1 > time2) { // More time value, most current time 
        return loc1; 
       } else { 
        return loc2; 
       } 
      } else { 
       float accuracy1 = loc1.Accuracy; 
       float accuracy2 = loc2.Accuracy; 

       // Smaller the value (meters), the greater the accuracy 
       if (accuracy1 < accuracy2) { 
        return loc1; 
       } else { 
        return loc2; 
       } 
      } 
     } 

     public void OnStop() { 
      locMgr = null; 
     } 

     public void OnPause() { 
      locMgr?.RemoveUpdates(this); 
     } 

     public void OnStart() { 
     } 

     public void OnResume() { 
      if (locMgr == null || currentLocation == null) { 
       getLocation(); 
      } 
     } 

     public bool canGetLocation() { 
      return locationAvailable; 
     } 

     public LatLng getLatLng() { 
      return new LatLng(currentLocation.Latitude, currentLocation.Longitude); 
     } 

     public double getLatitude() { 
      return currentLocation.Latitude; 
     } 

     public double getLongitude() { 
      return currentLocation.Longitude; 
     } 

     public void OnLocationChanged(Location location) { 
      currentLocation = getBestLocation(currentLocation, location); 
     } 

     // User disabled a provider 
     public void OnProviderDisabled(string provider) { 
      getLocation(); // Check if all providers are disabled and pop up alertDialog if they are so 
     } 

     // User enabled a provider 
     public void OnProviderEnabled(string provider) { 
      getLocation(); // Update all available providers for getting the best provider available 
     } 

     public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras) { 
     } 
    } 
} 

using Android.App; 
using Android.Gms.Common; 
using Android.Gms.Common.Apis; 
using Android.Gms.Maps.Model; 
using Android.Gms.Maps; 
using Android.Locations; 
using Android.Content; 
using Android.Widget; 

namespace Maps.Droid.LocationService { 
    public class LocationTracker { 
     public static long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 5 meters 
     public static long MIN_TIME_BW_UPDATES = 1000 * 15; // 15 seconds ok, 5 seconds really fast, 30s slow 
     public static float DEFAULT_ZOOM = 16f; 

     private bool hasGooglePlayServices; 
     public GoogleApiClient mGoogleApiClient; 
     private FusedLocation fusedLocation; 
     private AndroidLocation androidLocation; 
     private bool locationIsDisabled; 

     public LocationTracker(Activity activity) { 
      if (locationIsDisabled = isLocationDisabled(activity)) { 
       showSettingsAlert(activity); 
      } else { 
       hasGooglePlayServices = checkPlayServices(activity); 

       if (hasGooglePlayServices) { 
        fusedLocation = new FusedLocation(activity); 
       } else { 
        androidLocation = new AndroidLocation(activity); 
       } 
      } 
     } 

     private void showSettingsAlert(Activity activity) { 
      AlertDialog.Builder builder = new AlertDialog.Builder(activity); 
      builder.SetTitle("Location Services Not Active"); 
      builder.SetMessage("Please enable Location Services and GPS"); 
      builder.SetPositiveButton("OK", delegate { 
       // Show location settings when the user acknowledges the alert dialog 
       var intent = new Intent(Android.Provider.Settings.ActionLocationSourceSettings); 
       activity.StartActivity(intent); 
      }); 
      builder.SetNegativeButton("Cancel", delegate { 
       Toast.MakeText(activity, "Location disabled by user", ToastLength.Short).Show(); 
      }); 
      AlertDialog alertDialog = builder.Create(); 
      alertDialog.SetCanceledOnTouchOutside(false); 
      alertDialog.Show(); 
     } 

     private bool isLocationDisabled(Activity activity) { 
      LocationManager locMgr = activity.GetSystemService(Context.LocationService) as LocationManager; 

      // More precise, More power consuming 
      bool isGPSEnabled = locMgr.IsProviderEnabled(LocationManager.GpsProvider); 

      // Varying precision, Less power consuming. Combination of WiFi and Cellular data 
      bool isNetworkEnabled = locMgr.IsProviderEnabled(LocationManager.NetworkProvider); 

      // UNCOMMENT 
      // bool isPassiveEnabled = locMgr.IsProviderEnabled(LocationManager.PassiveProvider); 

      // UNCOMMENT 
      // return !isGPSEnabled && !isNetworkEnabled && !isPassiveEnabled; // True only when the 3 location services are disabled 

      return !isGPSEnabled && !isNetworkEnabled; // True only when both location services are disabled 
     } 

     // Call this method at OnMapReady callback if initial zooming/animation on user's location is desired 
     public void setMap(GoogleMap map) { 
      if (locationIsDisabled) { 
       return; 
      } 

      if (hasGooglePlayServices) { 
       fusedLocation.setMap(map); 
      } else { 
       androidLocation.setMap(map); 
      } 
     } 

     public void OnResume() { 
      if (locationIsDisabled) { 
       return; 
      } 

      if (hasGooglePlayServices) { 
       fusedLocation.OnResume(); 
      } else { 
       androidLocation.OnResume(); 
      } 
     } 

     public void OnPause() { 
      if (locationIsDisabled) { 
       return; 
      } 

      if (hasGooglePlayServices) { 
       fusedLocation.OnPause(); 
      } else { 
       androidLocation.OnPause(); 
      } 
     } 

     public void OnStart() { 
      if (locationIsDisabled) { 
       return; 
      } 

      if (hasGooglePlayServices) { 
       fusedLocation.OnStart(); 
      } else { 
       androidLocation.OnStart(); 
      } 
     } 

     public void OnStop() { 
      if (locationIsDisabled) { 
       return; 
      } 

      if (hasGooglePlayServices) { 
       fusedLocation.OnStop(); 
      } else { 
       androidLocation.OnStop(); 
      } 
     } 

     private bool checkPlayServices(Activity activity) { 
      GoogleApiAvailability apiAvailability = GoogleApiAvailability.Instance; 
      int resultCode = apiAvailability.IsGooglePlayServicesAvailable(activity); 
      if (resultCode == ConnectionResult.Success) { 
       return true; 
      } 
      return false; 
     } 

     public double getLatitude() { 
      if (locationIsDisabled) { 
       return 0; 
      } 

      if (hasGooglePlayServices) { 
       return fusedLocation.getCurrentLocation() == null ? 0.0 : fusedLocation.getLatitude(); 
      } else { 
       return androidLocation.getCurrentLocation() == null ? 0.0 : androidLocation.getLatitude(); 
      } 
     } 

     public double getLongitude() { 
      if (locationIsDisabled) { 
       return 0; 
      } 

      if (hasGooglePlayServices) { 
       return fusedLocation.getCurrentLocation() == null ? 0.0 : fusedLocation.getLongitude(); 
      } else { 
       return androidLocation.getCurrentLocation() == null ? 0.0 : androidLocation.getLongitude(); 
      } 
     } 

     public bool canGetLocation() { 
      if (locationIsDisabled) { 
       return false; 
      } 

      if (hasGooglePlayServices) { 
       return fusedLocation.canGetLocation(); 
      } else { 
       return androidLocation.canGetLocation(); 
      } 
     } 

     public LatLng getLatLng() { 
      if (locationIsDisabled) { 
       return null; 
      } 

      LatLng latlng; 
      if (hasGooglePlayServices) { 
       latlng = fusedLocation.getLatLng(); 
      } else { 
       latlng = androidLocation.getLatLng(); 
      } 

      return latlng; 
     } 

     public Location getCurrentLocation() { 
      if (hasGooglePlayServices) { 
       return fusedLocation.getCurrentLocation(); 
      } else { 
       return androidLocation.getCurrentLocation(); 
      } 
     } 
    } 
} 

然后把它用在你的片段或活动:

在OnCreate中初始化它:

Location tracker = new LocationTracker(this.Activity); 

做出所指的生命周期:

public override void OnResume() { 
      base.OnResume(); 
      tracker.OnResume(); 
     } 

     public override void OnPause() { 
      base.OnPause(); 
      tracker.OnPause(); 
     } 

     public override void OnStart() { 
      base.OnStart(); 
      tracker.OnStart(); 
     } 

     public override void OnStop() { 
      base.OnStop(); 
      tracker.OnStop(); 
     } 

,如果你希望动画在开始时用户的位置放大,那么你有当你有GoogleMap的加入这行代码:这个解决方案

tracker.setMap(googleMap); // Invoke this method if zooming/animating to the user's location is desired 

花了许多天。希望它能帮助别人!

+0

我遇到的问题是在OnConnected方法之前调用方法OnMapReady。因此,当我在OnMapReady上获取经度和纬度时,仍然为空 –

+0

在OnLocationChanged方法中,您可以重新设置地图的动画效果。也许这个链接可以帮助你:http://stackoverflow.com/questions/33739971/how-to-show-my-current-location-in-google-map-android-using-google-api-client – Onur

相关问题