Android Xamarin-不会使用fusedLocationAPI.requestLocationUpdates调用onLocationChanged

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

我一直在尝试使用fusedLocationApi获取当前位置。我正在将Xamarin与模拟的Nexus5(Genymotion)一起在设备上进行测试。根据在线文档,我们可以通过以下方式请求位置更新:

FusedLocationApi.RequestLocationUpdate

然后回调到:

onLocation已更改(位置)

它在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;
        }
    }
}
使用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;
        }
    }   
}