Android Xamarin:GoogleAppClient在OnConnect&;OnLocationChanged从未调用
我正在用Xamarin构建一个Android应用程序,它应该使用定位服务 在OnCreate中,我构建了GoogleAppClient: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.
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 };