Xamarin:在OnConnected& amp;之后,GoogleApiClient为空OnLocationChanged从未调用过

时间:2016-12-30 22:48:21

标签: android xamarin xamarin.android google-play-services

我正在使用Xamarin构建一个应该使用位置服务的Android应用程序。

在OnCreate中,我构建了GoogleApiClient:

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);
        global::Xamarin.Forms.Forms.Init (this, bundle);
        LoadApplication (new KMN.App ());

        apiClient = new GoogleApiClient.Builder(this, this, this).AddApi(LocationServices.API).Build();
        apiClient.Connect();
    }
之后

apiClient是!= null。比我进入:

    public void OnConnected(Bundle connectionHint)
    {
        LocationRequest locRequest = new LocationRequest();
        locRequest.SetPriority(LocationRequest.PriorityBalancedPowerAccuracy);
        locRequest.SetFastestInterval(500);
        locRequest.SetInterval(1000);

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

这里apiClient仍然是!= null。

永远不会调用此方法:

    public void OnLocationChanged(Android.Locations.Location location)
    {
        LastLocation = location;
    }

当我从UI调用此方法时,apiClient为null:

    public Adresse getAdresse()
    {
        if (LastLocation!= null)
        { 
            return new Adresse()
            {
                Latitude = LastLocation.Latitude,
                Longitude = LastLocation.Longitude
            };
        }
        else
        {
            return new Adresse()
            {
                Latitude = 0,
                Longitude = 0
            };
        }
    }

1 个答案:

答案 0 :(得分:0)

你可以使用在Android Application子类中定义的静态变量等......但这是我首选的方式......; - )

DS接口和一些帮助程序类:

public interface ILocationService : IDisposable
{
    Task<bool> Init();
    MyLocation Currentlocation();
    void Subscribe(EventHandler handler);
    void Unsubscribe(EventHandler handler);
}

public class MyLocation
{
    public MyLocation(double Latitude, double Longitude)
    {
        this.Latitude = Latitude;
        this.Longitude = Longitude;
    }

    public double Latitude { get; private set; }
    public double Longitude { get; private set; }
}

public class LocationEventArgs<T> : EventArgs
{
    public T EventData { get; private set; }

    public LocationEventArgs(T EventData)
    {
        this.EventData = EventData;
    }
}

Android依赖项实施:

public class LocationService : Java.Lang.Object, 
        ILocationService,
        GoogleApiClient.IConnectionCallbacks,
        GoogleApiClient.IOnConnectionFailedListener,
        Android.Gms.Location.ILocationListener,
        IDisposable
{
    bool _init;
    GoogleApiClient gClient;
    LocationRequest locRequest;
    ManualResetEventSlim resetEvent;
    EventHandler eventHandler;

    public async Task<bool> Init()
    {
        await Task.Run(() =>
        {
            if (!_init)
            {
                resetEvent = new ManualResetEventSlim();
                gClient = new GoogleApiClient.Builder(Forms.Context, this, this).AddApi(LocationServices.API).Build();
                _init = true;
            }
            resetEvent.Reset();
            gClient.Connect();
            resetEvent.Wait();
        });             
        return gClient.IsConnected;
    }

    public new void Dispose()
    {
        resetEvent?.Dispose();
        if (gClient != null)
            LocationServices.FusedLocationApi.RemoveLocationUpdates(gClient, this);
        gClient?.Dispose();
        base.Dispose();
    }

    public void OnConnected(Bundle connectionHint)
    {
        resetEvent.Set();
    }

    public void OnConnectionFailed(ConnectionResult result)
    {
        resetEvent.Set();
    }

    public void OnConnectionSuspended(int cause)
    {
        LocationServices.FusedLocationApi.RemoveLocationUpdates(gClient, this);
    }

    public void OnLocationChanged(Android.Locations.Location location)
    {
        Log.Debug("SO", location.ToString());
        eventHandler?.Invoke(null, new LocationEventArgs<MyLocation>(new MyLocation(location.Latitude, location.Longitude)));
    }

    public void Subscribe(EventHandler locationHandler)
    {
        locRequest = new LocationRequest();
        locRequest.SetPriority(LocationRequest.PriorityBalancedPowerAccuracy);
        locRequest.SetFastestInterval(100);
        locRequest.SetInterval(5000);

        eventHandler += locationHandler;
        LocationServices.FusedLocationApi.RequestLocationUpdates(gClient, locRequest, this);
    }

    public void Unsubscribe(EventHandler locationHandler)
    {
        LocationServices.FusedLocationApi.RemoveLocationUpdates(gClient, this);
        eventHandler -= locationHandler;
    }

    public MyLocation Currentlocation()
    {
        if (gClient != null)
        {
            var lastLocation = LocationServices.FusedLocationApi.GetLastLocation(gClient);
            Log.Debug("SO", lastLocation.ToString());

            if (lastLocation != null)
                return new MyLocation(lastLocation.Latitude, lastLocation.Longitude);
        }
        return null;
    }
}

Xamarin.Forms项目中的用法:

var startLocationUpdates = new Command(async () =>
{
    if (await DependencyService.Get<ILocationService>().Init())
    {
        // Subscribe to the location change events...
        DependencyService.Get<ILocationService>().Subscribe((sender, e) =>
        {
            var loc = (e as LocationEventArgs<MyLocation>).EventData;
            System.Diagnostics.Debug.WriteLine($"{loc.Latitude}:{loc.Longitude}");
        });

        // Or just grab the Fused-based LastLocation (it might not be  available!)
        var loc2 = DependencyService.Get<ILocationService>().Currentlocation();
        if (loc2 != null)
            System.Diagnostics.Debug.WriteLine($"{loc2?.Latitude}:{loc2?.Longitude}");
    }
});
var button = new Button { Text = "Start Location Updates", Command = startLocationUpdates };