Android Xamarin-不会使用fusedLocationAPI.requestLocationUpdates调用onLocationChanged
我一直在尝试使用fusedLocationApi获取当前位置。我正在将Xamarin与模拟的Nexus5(Genymotion)一起在设备上进行测试。根据在线文档,我们可以通过以下方式请求位置更新: FusedLocationApi.RequestLocationUpdate 然后回调到: onLocation已更改(位置) 它在api 23下工作Android Xamarin-不会使用fusedLocationAPI.requestLocationUpdates调用onLocationChanged,android,xamarin,location,Android,Xamarin,Location,我一直在尝试使用fusedLocationApi获取当前位置。我正在将Xamarin与模拟的Nexus5(Genymotion)一起在设备上进行测试。根据在线文档,我们可以通过以下方式请求位置更新: FusedLocationApi.RequestLocationUpdate 然后回调到: onLocation已更改(位置) 它在api 23下工作 using Android.App; using Android.OS; using Android.Views; using System.Thr
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;
}
}
}
使用Android.App;
使用Android.OS;
使用Android.Views;
使用System.Threading.Tasks;
使用Android.Gms.Maps;
使用Android.Gms.Common;
使用Android.Locations;
使用Android.Gms.Common.api;
使用Android.Gms.Location;
使用Android.Gms.Maps.Model;
使用安卓系统;
使用Android.Support.Design.Widget;
使用Android.Content.PM;
命名空间停止
{
公共类MapFragment:FocuableFragment、IOnMapReadyCallback、Android.Gms.Common.API.GoogleAppClient.IOnConnectionFailedListener、Android.Gms.Common.API.GoogleAppClient.IConnectionCallbacks、ILocationSource、Android.Gms.Location.ILocationListener
{
私有视图(u视图),;
只读字符串[]权限位置=
{
Manifest.Permission.accessLocation,
Manifest.Permission.AccessFineLocation,
Manifest.Permission.AccessNetworkState
};
const int RequestLocationId=0;
私人GoogleapClient MGoogleapClient;
专用静态定位请求;
私有ILocationSourceOnLocationChangedListener mMapLocationListener;
连接失败的公共void(连接结果)
{
//无所事事
}
未连接的公共无效(捆绑连接提示)
{
LocationServices.FusedLocationApi.RequestLocationUpdate(
MGoogleapClient,
要求
这个);//位置侦听器
}
连接上的公共无效已暂停(内部原因)
{
//无所事事
}
已更改位置上的公共无效(位置)
{
var newLocation=位置;
if(mMapLocationListener!=null)
{
mMapLocationListener.OnLocationChanged(位置);
}
}
public void Activate(ILocationSourceOnLocationChangedListener侦听器)
{
mMapLocationListener=侦听器;
}
公开作废
{
mMapLocationListener=null;
}
私有SupportMapFragment\u SupportMapFragment;
私人谷歌地图(GoogleMap);;
私有视图组_mapcardLayout;
公共覆盖void onFocus()
{
}
public override void offFocus()
{
}
创建时公共覆盖无效(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
//在这里创建你的片段
}
创建视图上的公共覆盖视图(布局、充气机、视图组容器、捆绑包保存状态)
{
//使用此选项可返回此片段的自定义视图
_视图=充气机。充气(Resource.Layout.MapCard,container,false);
_mapcardLayout=(ViewGroup)\ u view.FindViewById(Resource.Id.mapcardLayout);
/*
*创建地图
*/
_supportMapFragment=新的supportMapFragment();
Android.Support.V4.App.FragmentTransaction=FragmentManager.BeginTransaction();
添加(Resource.Id.mainMapFragmentMapWrapper,\u supportMapFragment);
SetTransition(Android.Support.V4.App.FragmentTransaction.TransitFragmentFade);
Commit();
_supportMapFragment.GetMapAsync(此文件);
返回视图;
}
公营机构
{
if(mGoogleApiClient!=null&!mGoogleApiClient.IsConnected)
{
mGoogleApiClient.Connect();
}
}
公营机构
{
if(mGoogleApiClient!=null&&mGoogleApiClient.IsConnected)
{
mGoogleApiClient.Disconnect();
}
}
4月1日公开作废(谷歌地图谷歌地图)
{
_谷歌地图=谷歌地图;
_googleMap.UiSettings.MapToolbarEnabled=false;
_googleMap.UiSettings.CompassEnabled=false;
_googleMap.UiSettings.MyLocationButtonEnabled=false;
_googleMap.UiSettings.TiltGesturesEnabled=false;
_googleMap.MapType=googleMap.MapTypeHybrid;
TryGetLocationAsync();
}
异步void TryGetLocationAsync()
{
如果((int)Build.VERSION.SdkInt<23)
{
Snackbar.Make(_mapcardLayout,“Aktiverar gps(lågenergi-läge används)”,Snackbar.LengthShort.Show();
EnableLocation();
返回;
}
等待GetLocationPermissionAsync();
}
异步任务GetLocationPermissionAsync()
{
//检查我们组中是否有任何权限可用,如果有,则所有权限都可用
const string permission=Manifest.permission.AccessFineLocation;
if(Application.Context.CheckSelfPermission(permission)==(int)permission.grated)
{
Snackbar.Make(_mapcardLayout,“Aktiverar gps(lågenergi-läge används)”,Snackbar.LengthShort.Show();
EnableLocation();
返回1;
}
//需要请求许可吗
如果(应显示请求许可理由(许可))
{
//向用户解释为什么我们需要阅读联系人
Snackbar.Make(_mapcardLayout,“全球定位系统(lågenergi-läge)behövs för att visa vart duär.”,Snackbar.Lengthindefined)
.SetAction(“确定”,v=>RequestPermissions(
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;
}
}
}