我一直在尝试使用fusedLocationApi来获取当前位置。我使用Xamarin和模拟的Nexus 5(Genymotion)也在设备上进行测试。根据在线文档https://developer.android.com/training/location/receive-location-updates.html?hl=es,我们可以使用以下方式请求位置更新:
FusedLocationApi.requestLocationUpdates
并且回调转到:
onLocationChanged(位置位置)
它的作品低于api 23 ..
using Android.App;
using Android.OS;
using Android.Views;
using System.Threading.Tasks;
using Android.Gms.Maps;
using Android.Gms.Common;
using Android.Locations;
using Android.Gms.Common.Apis;
using Android.Gms.Location;
using Android.Gms.Maps.Model;
using Android;
using Android.Support.Design.Widget;
using Android.Content.PM;
namespace stops
{
public class MapFragment : FocuableFragment, IOnMapReadyCallback, Android.Gms.Common.Apis.GoogleApiClient.IOnConnectionFailedListener, Android.Gms.Common.Apis.GoogleApiClient.IConnectionCallbacks, ILocationSource, Android.Gms.Location.ILocationListener
{
private View _view;
readonly string[] PermissionsLocation =
{
Manifest.Permission.AccessCoarseLocation,
Manifest.Permission.AccessFineLocation,
Manifest.Permission.AccessNetworkState
};
const int RequestLocationId = 0;
private GoogleApiClient mGoogleApiClient;
private static LocationRequest REQUEST;
private ILocationSourceOnLocationChangedListener mMapLocationListener;
public void OnConnectionFailed(ConnectionResult result)
{
// Do nothing
}
public void OnConnected(Bundle connectionHint)
{
LocationServices.FusedLocationApi.RequestLocationUpdates(
mGoogleApiClient,
REQUEST,
this); // LocationListener
}
public void OnConnectionSuspended(int cause)
{
// Do nothing
}
public void OnLocationChanged(Location location)
{
var newLocation = location;
if (mMapLocationListener != null)
{
mMapLocationListener.OnLocationChanged(location);
}
}
public void Activate(ILocationSourceOnLocationChangedListener listener)
{
mMapLocationListener = listener;
}
public void Deactivate()
{
mMapLocationListener = null;
}
private SupportMapFragment _supportMapFragment;
private GoogleMap _googleMap;
private ViewGroup _mapcardLayout;
public override void onFocus()
{
}
public override void offFocus()
{
}
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
_view = inflater.Inflate(Resource.Layout.MapCard, container, false);
_mapcardLayout = (ViewGroup)_view.FindViewById(Resource.Id.mapcardLayout);
/*
* Create the map
*/
_supportMapFragment = new SupportMapFragment();
Android.Support.V4.App.FragmentTransaction transaction = FragmentManager.BeginTransaction();
transaction.Add(Resource.Id.mainMapFragmentMapWrapper, _supportMapFragment);
transaction.SetTransition(Android.Support.V4.App.FragmentTransaction.TransitFragmentFade);
transaction.Commit();
_supportMapFragment.GetMapAsync(this);
return _view;
}
public void EnableAPI()
{
if (mGoogleApiClient != null && !mGoogleApiClient.IsConnected)
{
mGoogleApiClient.Connect();
}
}
public void DisableAPI()
{
if (mGoogleApiClient != null && mGoogleApiClient.IsConnected)
{
mGoogleApiClient.Disconnect();
}
}
public void OnMapReady(GoogleMap googleMap)
{
_googleMap = googleMap;
_googleMap.UiSettings.MapToolbarEnabled = false;
_googleMap.UiSettings.CompassEnabled = false;
_googleMap.UiSettings.MyLocationButtonEnabled = false;
_googleMap.UiSettings.TiltGesturesEnabled = false;
_googleMap.MapType = GoogleMap.MapTypeHybrid;
TryGetLocationAsync();
}
async void TryGetLocationAsync()
{
if ((int)Build.VERSION.SdkInt < 23)
{
Snackbar.Make(_mapcardLayout, "Aktiverar gps (lågenergi-läge används)", Snackbar.LengthShort).Show();
EnableLocation();
return;
}
await GetLocationPermissionAsync();
}
async Task<int> GetLocationPermissionAsync()
{
//Check to see if any permission in our group is available, if one, then all are
const string permission = Manifest.Permission.AccessFineLocation;
if (Application.Context.CheckSelfPermission(permission) == (int)Permission.Granted)
{
Snackbar.Make(_mapcardLayout, "Aktiverar gps (lågenergi-läge används)", Snackbar.LengthShort).Show();
EnableLocation();
return 1;
}
//need to request permission
if (ShouldShowRequestPermissionRationale(permission))
{
//Explain to the user why we need to read the contacts
Snackbar.Make(_mapcardLayout, "GPS (lågenergi-läge) behövs för att visa vart du är.", Snackbar.LengthIndefinite)
.SetAction("OK", v => RequestPermissions(PermissionsLocation, RequestLocationId))
.Show();
return 1;
}
Snackbar.Make(_mapcardLayout, "GPS (lågenergi-läge) behövs för att visa vart du är.", Snackbar.LengthLong)
.Show();
await Task.Delay(1250);
//Finally request permissions with the list of permissions and Id
RequestPermissions(PermissionsLocation, RequestLocationId);
return 1;
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
switch (requestCode)
{
case RequestLocationId:
{
if (grantResults[0] == Permission.Granted)
{
//Permission granted
var snack = Snackbar.Make(_mapcardLayout, "Aktiverar GPS.", Snackbar.LengthShort);
snack.Show();
EnableLocation();
}
else
{
//Permission Denied :(
//Disabling location functionality
var snack = Snackbar.Make(_mapcardLayout, "Användning av GPS nekad.", Snackbar.LengthShort);
snack.Show();
}
}
break;
}
}
public void EnableLocation()
{
REQUEST = LocationRequest.Create().SetPriority(LocationRequest.PriorityBalancedPowerAccuracy);
_googleMap.MyLocationEnabled = true;
_googleMap.UiSettings.MapToolbarEnabled = false;
_googleMap.UiSettings.CompassEnabled = false;
_googleMap.UiSettings.MyLocationButtonEnabled = false;
_googleMap.UiSettings.TiltGesturesEnabled = false;
mGoogleApiClient = new GoogleApiClient.Builder(Activity)
.AddApi(LocationServices.API)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(this)
.Build();
mGoogleApiClient.Connect();
_googleMap.SetLocationSource(this);
/*
* Init GPS posistioning
*/
PositionCamera(Util.Util.GetLastKnownLocation());
}
Location PositionCamera(Location location)
{
if (location != null)
{
_googleMap.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(new LatLng(57.695443, 11.992507), 15.0f));
}
else {
_googleMap.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(new LatLng(57.695443, 11.992507), 15.0f));
}
return location;
}
}
}
解决方案
using Android.App;
using Android.OS;
using Android.Views;
using System.Threading.Tasks;
using Android.Gms.Maps;
using Android.Gms.Common;
using Android.Locations;
using Android.Gms.Common.Apis;
using Android.Gms.Location;
using Android.Gms.Maps.Model;
using Android;
using Android.Support.Design.Widget;
using Android.Content.PM;
using Java.Lang;
using Android.Util;
using System;
using Android.Content;
namespace stops
{
public class MapFragment : FocuableFragment, Android.Gms.Maps.IOnMapReadyCallback, GoogleApiClient.IConnectionCallbacks,
GoogleApiClient.IOnConnectionFailedListener, Android.Gms.Location.ILocationListener, Android.Gms.Maps.ILocationSource
{
readonly string[] PermissionsLocation =
{
Manifest.Permission.AccessCoarseLocation,
Manifest.Permission.AccessFineLocation,
Manifest.Permission.AccessNetworkState
};
const int RequestLocationId = 0;
private View _view;
private SupportMapFragment _supportMapFragment;
private GoogleMap _googleMap;
protected const string TAG = "location-settings";
protected const int REQUEST_CHECK_SETTINGS = 0x1;
public const long UPDATE_INTERVAL_IN_MILLISECONDS = 5000;
public const long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
protected const string KEY_REQUESTING_LOCATION_UPDATES = "requesting-location-updates";
protected const string KEY_LOCATION = "location";
protected const string KEY_LAST_UPDATED_TIME_STRING = "last-updated-time-string";
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
protected LocationSettingsRequest mLocationSettingsRequest;
protected Location mCurrentLocation;
private ViewGroup _mapcardLayout;
protected bool mRequestingLocationUpdates;
protected string mLastUpdateTime;
private ILocationSourceOnLocationChangedListener mMapLocationListener;
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
_view = inflater.Inflate(Resource.Layout.MapCard, container, false);
_mapcardLayout = (ViewGroup)_view.FindViewById(Resource.Id.mapcardLayout);
/*
* Create the map
*/
_supportMapFragment = new SupportMapFragment();
Android.Support.V4.App.FragmentTransaction transaction = FragmentManager.BeginTransaction();
transaction.Add(Resource.Id.mainMapFragmentMapWrapper, _supportMapFragment);
transaction.SetTransition(Android.Support.V4.App.FragmentTransaction.TransitFragmentFade);
transaction.Commit();
_supportMapFragment.GetMapAsync(this);
return _view;
}
async void TryGetLocationAsync()
{
if (Build.VERSION.SdkInt > Android.OS.BuildVersionCodes.Lollipop)
{
await GetLocationPermissionAsync();
return;
}
await CheckLocationSettings();
}
async Task<int> GetLocationPermissionAsync()
{
//Check to see if any permission in our group is available, if one, then all are
const string permission = Manifest.Permission.AccessFineLocation;
if (Application.Context.CheckSelfPermission(permission) == (int)Permission.Granted)
{
Snackbar.Make(_mapcardLayout, "Aktiverar gps (lågenergi-läge används)", Snackbar.LengthShort).Show();
await CheckLocationSettings();
return 1;
}
//need to request permission
if (ShouldShowRequestPermissionRationale(permission))
{
//Explain to the user why we need to read the contacts
Snackbar.Make(_mapcardLayout, "GPS (lågenergi-läge) behövs för att visa vart du är.", Snackbar.LengthIndefinite)
.SetAction("OK", v => RequestPermissions(PermissionsLocation, RequestLocationId))
.Show();
return 1;
}
Snackbar.Make(_mapcardLayout, "GPS (lågenergi-läge) behövs för att visa vart du är.", Snackbar.LengthLong)
.Show();
await Task.Delay(1250);
//Finally request permissions with the list of permissions and Id
RequestPermissions(PermissionsLocation, RequestLocationId);
return 1;
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
switch (requestCode)
{
case RequestLocationId:
{
if (grantResults[0] == Permission.Granted)
{
//Permission granted
var snack = Snackbar.Make(_mapcardLayout, "Aktiverar GPS.", Snackbar.LengthShort);
snack.Show();
CheckLocationSettings();
}
else
{
//Permission Denied :(
//Disabling location functionality
var snack = Snackbar.Make(_mapcardLayout, "Användning av GPS nekad.", Snackbar.LengthShort);
snack.Show();
}
}
break;
}
}
public void OnMapReady(GoogleMap googleMap)
{
_googleMap = googleMap;
_googleMap.UiSettings.MapToolbarEnabled = false;
_googleMap.UiSettings.CompassEnabled = false;
_googleMap.UiSettings.MyLocationButtonEnabled = false;
_googleMap.UiSettings.TiltGesturesEnabled = false;
_googleMap.MapType = GoogleMap.MapTypeHybrid;
PositionCamera();
BuildGoogleApiClient();
EnableAPI();
CreateLocationRequest();
BuildLocationSettingsRequest();
TryGetLocationAsync();
}
void PositionCamera()
{
_googleMap.AnimateCamera(CameraUpdateFactory.NewLatLngZoom(new LatLng(57.695443, 11.992507), 15.0f));
}
protected void BuildGoogleApiClient()
{
Log.Info(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(Activity)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(this)
.AddApi(LocationServices.API)
.Build();
}
public void EnableAPI()
{
if (mGoogleApiClient != null && !mGoogleApiClient.IsConnected)
{
mGoogleApiClient.Connect();
}
}
public void DisableAPI()
{
if (mGoogleApiClient != null && mGoogleApiClient.IsConnected)
{
mGoogleApiClient.Disconnect();
}
}
protected void CreateLocationRequest()
{
mLocationRequest = new LocationRequest();
mLocationRequest.SetInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.SetFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);
}
protected void BuildLocationSettingsRequest()
{
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.AddLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.Build();
}
protected async Task CheckLocationSettings()
{
var result = await LocationServices.SettingsApi.CheckLocationSettingsAsync(
mGoogleApiClient, mLocationSettingsRequest);
await HandleResult(result);
}
public async Task HandleResult(LocationSettingsResult locationSettingsResult)
{
var status = locationSettingsResult.Status;
switch (status.StatusCode)
{
case CommonStatusCodes.Success:
Log.Info(TAG, "All location settings are satisfied.");
await StartLocationUpdates();
break;
case CommonStatusCodes.ResolutionRequired:
Log.Info(TAG, "Location settings are not satisfied. Show the user a dialog to" +
"upgrade location settings ");
try
{
status.StartResolutionForResult(Activity, REQUEST_CHECK_SETTINGS);
}
catch (IntentSender.SendIntentException)
{
Log.Info(TAG, "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SettingsChangeUnavailable:
Log.Info(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " +
"not created.");
break;
}
}
protected async Task StartLocationUpdates()
{
await LocationServices.FusedLocationApi.RequestLocationUpdates(
mGoogleApiClient,
mLocationRequest,
this
);
_googleMap.MyLocationEnabled = true;
_googleMap.SetLocationSource(this);
mRequestingLocationUpdates = true;
}
protected async Task StopLocationUpdates()
{
await LocationServices.FusedLocationApi.RemoveLocationUpdates(
mGoogleApiClient,
this
);
mRequestingLocationUpdates = false;
}
public void OnConnectionFailed(ConnectionResult result)
{
Log.Info(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.ErrorCode);
}
public void OnLocationChanged(Location location)
{
mCurrentLocation = location;
mLastUpdateTime = DateTime.Now.TimeOfDay.ToString();
if (mMapLocationListener != null)
{
mMapLocationListener.OnLocationChanged(location);
}
}
public void OnConnected(Bundle connectionHint)
{
if (mCurrentLocation == null)
{
mCurrentLocation = LocationServices.FusedLocationApi.GetLastLocation(mGoogleApiClient);
mLastUpdateTime = DateTime.Now.TimeOfDay.ToString();
}
}
public void OnConnectionSuspended(int cause)
{
Log.Info(TAG, "Connection suspended");
}
public void Activate(ILocationSourceOnLocationChangedListener listener)
{
mMapLocationListener = listener;
}
public void Deactivate()
{
mMapLocationListener = null;
}
}
}