如何使用Xamarin在Android中同步获取GPS位置更新?
作者:互联网
具体来说,我正在使用Xamarin.Forms进行C#开发,但是在本机Android方面工作,编写了GPS包装类,该类可以通过依赖注入在Xamarin.Forms方面使用.在大多数情况下,关于Android,C#和Java之间的调用应该相同.
本质上,我在Android端的Geolocator对象(实现ILocationListener)中具有此方法:
public async Task<Tuple<bool, string, GPSData>> GetGPSData() {
gpsData = null;
var success = false;
var error = string.Empty;
if (!manager.IsProviderEnabled(LocationManager.GpsProvider)) {
//request permission or location services enabling
//set error
} else {
manager.RequestSingleUpdate(LocationManager.GpsProvider, this, null);
success = true;
}
return new Tuple<bool, string, GPSData>(success, error, gpsData);
}
和
public void OnLocationChanged(Location location) {
gpsData = new GPSData(location.Latitude, location.Longitude);
}
我希望能够调用GetGPSData并让它返回元组,目前关于元组的唯一重要的事情是gpsData已被填充.我知道找到修复方法可能需要几秒钟,因此我希望此方法是异步的一旦我真正需要该值,就可以在Xamarin.Forms端等待.
我的问题是我想不出一种方法来让manager.RequestSingleUpdate同步工作或进行其他工作.您调用该方法,然后最终触发OnLocationChanged.我试图投掷令人作呕的野蛮人
while (gpsData == null);
在强制它在OnLocationChanged被触发之前不要继续进行的调用之后,但是当我将该行放入时,永远不会调用OnLocationChanged.我假设这是因为OnLocationChanged是在同一线程而不是后台线程上调用的.
我有什么办法可以采取这种情况,并在OnLocationChanged触发之前不返回GetGPSData?
谢谢
编辑:要添加,此方法将不会定期调用.它是自发的,很少见,所以我不想使用RequestLocationUpdates,获取常规更新并返回最新的更新,因为这将需要始终打开GPS,而不必要地给电池下雨.
解决方法:
您可以使用TaskCompletionSource执行所需的操作.我遇到了同样的问题,这就是我解决的方法:
TaskCompletionSource<Tuple<bool, string, GPSData> tcs;
// No need for the method to be async, as nothing is await-ed inside it.
public Task<Tuple<bool, string, GPSData>> GetGPSData() {
tcs = new TaskCompletionSource<Tuple<bool, string, GPSData>>();
gpsData = null;
var success = false;
var error = string.Empty;
if (!manager.IsProviderEnabled(LocationManager.GpsProvider)) {
//request permission or location services enabling
//set error
tcs.TrySetException(new Exception("some error")); // This will throw on the await-ing caller of this method.
} else {
manager.RequestSingleUpdate(LocationManager.GpsProvider, this, null);
success = true;
}
//return new Tuple<bool, string, GPSData>(success, error, gpsData); <-- change this to:
return this.tcs.Task;
}
和:
public void OnLocationChanged(Location location) {
gpsData = new GPSData(location.Latitude, location.Longitude);
// Here you set the result of TaskCompletionSource. Your other method completes the task and returns the result to its caller.
tcs.TrySetResult(new Tuple<bool, string, GPSData>(false, "someString", gpsData));
}
标签:xamarin-android,xamarin-forms,gps,c,android 来源: https://codeday.me/bug/20191118/2028377.html