Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Xamarin:GoogleAppClient在OnConnect&;OnLocationChanged从未调用_Android_Xamarin_Xamarin.android_Google Play Services - Fatal编程技术网

Android Xamarin:GoogleAppClient在OnConnect&;OnLocationChanged从未调用

Android Xamarin:GoogleAppClient在OnConnect&;OnLocationChanged从未调用,android,xamarin,xamarin.android,google-play-services,Android,Xamarin,Xamarin.android,Google Play Services,我正在用Xamarin构建一个Android应用程序,它应该使用定位服务 在OnCreate中,我构建了GoogleAppClient: protected override void OnCreate (Bundle bundle) { base.OnCreate (bundle); global::Xamarin.Forms.Forms.Init (this, bundle); LoadApplication (new KMN.

我正在用Xamarin构建一个Android应用程序,它应该使用定位服务

在OnCreate中,我构建了GoogleAppClient:

    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是!=之后无效。然后我进入:

    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!=空

永远不会调用此方法:

    public void OnLocationChanged(Android.Locations.Location location)
    {
        LastLocation = location;
    }
当我从UI调用此方法时,ApicClient为空:

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

您可以使用安卓
应用程序
子类中定义的静态变量,等等。。。但这是我喜欢的方式…;-)

DS接口和一些助手类:
公共接口ILocationService:IDisposable
{
任务初始化();
MyLocation Currentlocation();
void Subscribe(EventHandler);
无效取消订阅(EventHandler);
}
公共类位置
{
公共位置(双纬度、双经度)
{
这个。纬度=纬度;
这个。经度=经度;
}
公共双纬度{get;私有集;}
公共双经度{get;私有集;}
}
公共类LocationEventArgs:EventArgs
{
公共T事件数据{get;private set;}
公共位置事件参数(T事件数据)
{
this.EventData=EventData;
}
}
Android依赖项实现:
公共类LocationService:Java.Lang.Object,
ILocationService,
GoogleAppClient.i连接回调,
GoogleAppClient.IOnConnectionFailedListener,
Android.Gms.Location.ILocationListener,
可识别
{
bool_init;
GoogleapClient gClient;
位置请求位置请求;
手动复位事件SLIM复位事件;
事件处理程序事件处理程序;
公共异步任务Init()
{
等待任务。运行(()=>
{
如果(!\u init)
{
resetEvent=新的手动ResetEventSlim();
gClient=new GoogleApiClient.Builder(Forms.Context,this,this).AddApi(LocationServices.API).Build();
_init=真;
}
resetEvent.Reset();
gClient.Connect();
resetEvent.Wait();
});             
返回gClient.IsConnected;
}
公开新的无效处置()
{
resetEvent?.Dispose();
如果(gClient!=null)
LocationServices.FusedLocationApi.RemovelocationUpdate(gClient,this);
gClient?.Dispose();
base.Dispose();
}
未连接的公共无效(捆绑连接提示)
{
resetEvent.Set();
}
连接失败的公共void(连接结果)
{
resetEvent.Set();
}
连接上的公共无效已暂停(内部原因)
{
LocationServices.FusedLocationApi.RemovelocationUpdate(gClient,this);
}
public void OnLocationChanged(Android.Locations.Location)
{
Log.Debug(“SO”,location.ToString());
eventHandler?.Invoke(null,新位置EventArgs(新的MyLocation(location.Latitude,location.Longitude));
}
公共无效订阅(EventHandler locationHandler)
{
locRequest=新LocationRequest();
LocalRequest.SetPriority(LocationRequest.PriorityBalancedPower准确性);
locRequest.setFastTestInterval(100);
locRequest.SetInterval(5000);
eventHandler+=locationHandler;
LocationServices.FusedLocationApi.RequestLocationUpdate(gClient,locRequest,this);
}
公共无效取消订阅(EventHandler locationHandler)
{
LocationServices.FusedLocationApi.RemovelocationUpdate(gClient,this);
eventHandler-=locationHandler;
}
公共MyLocation当前位置()
{
如果(gClient!=null)
{
var lastLocation=LocationServices.FusedLocationApi.GetLastLocation(gClient);
Log.Debug(“SO”,lastLocation.ToString());
if(lastLocation!=null)
返回新的MyLocation(lastLocation.Latitude,lastLocation.Longitude);
}
返回null;
}
}
在Xamarin.Forms项目中的用法:
var startLocationUpdates=new命令(异步()=>
{
if(等待DependencyService.Get().Init())
{
//订阅位置更改事件。。。
DependencyService.Get().Subscribe((发件人,e)=>
{
var loc=(e为LocationEventArgs).EventData;
System.Diagnostics.Debug.WriteLine($“{loc.Latitude}:{loc.Longitude}”);
});
//或者只需抓取基于Fused的LastLocation(可能不可用!)
var loc2=DependencyService.Get().Currentlocation();
如果(loc2!=null)
System.Diagnostics.Debug.WriteLine($“{loc2?.Latitude}:{loc2?.Longitude}”);
}
});
var button=new按钮{Text=“开始位置更新”,Command=startLocationUpdates};

我假设您正在通过表单的依赖项服务调用
GetAddresse
?您在哪里定义
apiClient
?如果它在您的
MainActivity
类中,并且您也在该类中为
getAddresse
实现DS接口,那么您需要在“重新创建”您的
MainActivity
类时重新思考您的方法,您是对的。我正在通过DependencyService调用getAddresse,并且在我的MainActivity中定义了ApicClient。正确的方法是什么?
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;
    }
}
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;
    }
}
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 };