Xamarin essentials 地理定位不起作用,GetLocationAsync 中断尝试
Xamarin essentials geolocation is not working, GetLocationAsync breaks out of try
所以我想获取用户位置并对其进行反向地理编码以获取地址和门牌号。
因此我安装了预发布包 Xamarin.Essentials。我想使用地理定位和地理编码 API,所以我写了一些代码,但代码在 GetCurrentLocation 的尝试中从未达到 if (location != null)
。
根据 Xam.Plugin.Geolocator 作者 James Montemagno 的说法,我认为 Xamarin.Essentials 处于预发布阶段并不重要:
I will continue to work and maintain my Plugins, but I do recommend you checkout Xamarin.Essentials to see if it is a great fit your app as it has been for all of mine!
我做了什么?
我在 Whosebug 上搜索了有关我遇到的问题的问题,但据我所知找不到可以帮助我的问题。
我看过的题目:
- Geolocation doesn't work iOS PCL Xamarin forms
- Xamarin - Geolocation doesnt work... But why
- Xamarin.Forms.Webview Crossplatform Geolocation, is it possible?
我也尝试过添加超时是否有效:var request = new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue );
但是我在该位置上同样遇到了同样的问题。它从未到达 if 语句。
我的代码:
FillInLocationInForm();
在我的页面构造函数中设置。
public Location location;
和public Placemark placemark;
设置在页面class。
这些是页面中的相关功能 class:
public async void FillInLocationInForm()
{
if (await GetCurrentLocation())
{
if (await ReverseGeocodeLocation())
{
await this.DisplayAlert("Location", placemark.AdminArea + " " + placemark.FeatureName + " " + placemark.Locality + " " + placemark.SubLocality + " " + placemark.SubAdminArea + " " + placemark.SubThoroughfare + " " + placemark.Thoroughfare, "Okay", "Okay");
}
}
}
public async Task<bool> GetCurrentLocation ()
{
try
{
var request = new GeolocationRequest(GeolocationAccuracy.Medium);
var location = await Geolocation.GetLocationAsync(request);
if (location != null)
{
this.location = location;
return await Task.FromResult(true);
}
}
catch (FeatureNotSupportedException fnsEx)
{
// Handle not supported on device exception
}
catch (PermissionException pEx)
{
// Handle permission exception
}
catch (Exception ex)
{
// Unable to get location
}
return await Task.FromResult(false);
}
public async Task<bool> ReverseGeocodeLocation()
{
try
{
var lat = location.Latitude;
var lon = location.Longitude;
var placemarks = await Geocoding.GetPlacemarksAsync(lat, lon);
var placemark = placemarks?.FirstOrDefault();
if (placemark != null)
{
//var geocodeAddress =
// $"AdminArea: {placemark.AdminArea}\n" +
// $"CountryCode: {placemark.CountryCode}\n" +
// $"CountryName: {placemark.CountryName}\n" +
// $"FeatureName: {placemark.FeatureName}\n" +
// $"Locality: {placemark.Locality}\n" +
// $"PostalCode: {placemark.PostalCode}\n" +
// $"SubAdminArea: {placemark.SubAdminArea}\n" +
// $"SubLocality: {placemark.SubLocality}\n" +
// $"SubThoroughfare: {placemark.SubThoroughfare}\n" +
// $"Thoroughfare: {placemark.Thoroughfare}\n";
//Console.WriteLine(geocodeAddress);
this.placemark = placemark;
return await Task.FromResult(true);
}
}
catch (FeatureNotSupportedException fnsEx)
{
// Feature not supported on device
}
catch (Exception ex)
{
// Handle exception that may have occurred in geocoding
}
return await Task.FromResult(false);
}
我还将这些权限添加到我的应用程序 AndroidManifest 并在运行时请求它们。我在我的应用程序设置中看到位置和存储都被选中了。:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
我正在关注的文档:
- For Geolocation this link (this is where I experience the null value with).
- For Geocoding this link.
感谢任何帮助。
编辑:
我有一种预感,我需要向 GetLocationAsync
添加一个取消标记,但我还不知道如何操作。我没有在 GeolocationRequest 旁边看到它:
编辑 2:
我添加了CancellationToken,但是if语句还是没有到达。可能我还没有用好
using System.Threading; // add above
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken cancelToken = source.Token;
var location = await Geolocation.GetLocationAsync(request, cancelToken);
编辑 3:
下图中的断点永远不会触发,这意味着永远不会到达 if 语句。代码以某种方式退出了 try,但没有进入其中一个 catch 语句。我现在在我的 catch 语句中使用 Console.WriteLine()
。我在设备日志中看不到任何内容。我在设备日志中看到的 catch 中测试了 Console.WriteLine()
。
看来,我等的时间不够长。正如杰森所说。
我第一次尝试添加超时是:
new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue);
不知何故上面的行不起作用。
无论如何添加 10 秒的时间跨度给了我一个位置:
var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
在我的情况下,在位置设置下打开 phone 的“提高准确性”选项很有帮助;至少 Android 是这样。
所以我想获取用户位置并对其进行反向地理编码以获取地址和门牌号。
因此我安装了预发布包 Xamarin.Essentials。我想使用地理定位和地理编码 API,所以我写了一些代码,但代码在 GetCurrentLocation 的尝试中从未达到 if (location != null)
。
根据 Xam.Plugin.Geolocator 作者 James Montemagno 的说法,我认为 Xamarin.Essentials 处于预发布阶段并不重要:
I will continue to work and maintain my Plugins, but I do recommend you checkout Xamarin.Essentials to see if it is a great fit your app as it has been for all of mine!
我做了什么?
我在 Whosebug 上搜索了有关我遇到的问题的问题,但据我所知找不到可以帮助我的问题。
我看过的题目:
- Geolocation doesn't work iOS PCL Xamarin forms
- Xamarin - Geolocation doesnt work... But why
- Xamarin.Forms.Webview Crossplatform Geolocation, is it possible?
我也尝试过添加超时是否有效:var request = new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue );
但是我在该位置上同样遇到了同样的问题。它从未到达 if 语句。
我的代码:
FillInLocationInForm();
在我的页面构造函数中设置。
public Location location;
和public Placemark placemark;
设置在页面class。
这些是页面中的相关功能 class:
public async void FillInLocationInForm()
{
if (await GetCurrentLocation())
{
if (await ReverseGeocodeLocation())
{
await this.DisplayAlert("Location", placemark.AdminArea + " " + placemark.FeatureName + " " + placemark.Locality + " " + placemark.SubLocality + " " + placemark.SubAdminArea + " " + placemark.SubThoroughfare + " " + placemark.Thoroughfare, "Okay", "Okay");
}
}
}
public async Task<bool> GetCurrentLocation ()
{
try
{
var request = new GeolocationRequest(GeolocationAccuracy.Medium);
var location = await Geolocation.GetLocationAsync(request);
if (location != null)
{
this.location = location;
return await Task.FromResult(true);
}
}
catch (FeatureNotSupportedException fnsEx)
{
// Handle not supported on device exception
}
catch (PermissionException pEx)
{
// Handle permission exception
}
catch (Exception ex)
{
// Unable to get location
}
return await Task.FromResult(false);
}
public async Task<bool> ReverseGeocodeLocation()
{
try
{
var lat = location.Latitude;
var lon = location.Longitude;
var placemarks = await Geocoding.GetPlacemarksAsync(lat, lon);
var placemark = placemarks?.FirstOrDefault();
if (placemark != null)
{
//var geocodeAddress =
// $"AdminArea: {placemark.AdminArea}\n" +
// $"CountryCode: {placemark.CountryCode}\n" +
// $"CountryName: {placemark.CountryName}\n" +
// $"FeatureName: {placemark.FeatureName}\n" +
// $"Locality: {placemark.Locality}\n" +
// $"PostalCode: {placemark.PostalCode}\n" +
// $"SubAdminArea: {placemark.SubAdminArea}\n" +
// $"SubLocality: {placemark.SubLocality}\n" +
// $"SubThoroughfare: {placemark.SubThoroughfare}\n" +
// $"Thoroughfare: {placemark.Thoroughfare}\n";
//Console.WriteLine(geocodeAddress);
this.placemark = placemark;
return await Task.FromResult(true);
}
}
catch (FeatureNotSupportedException fnsEx)
{
// Feature not supported on device
}
catch (Exception ex)
{
// Handle exception that may have occurred in geocoding
}
return await Task.FromResult(false);
}
我还将这些权限添加到我的应用程序 AndroidManifest 并在运行时请求它们。我在我的应用程序设置中看到位置和存储都被选中了。:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
我正在关注的文档:
- For Geolocation this link (this is where I experience the null value with).
- For Geocoding this link.
感谢任何帮助。
编辑:
我有一种预感,我需要向 GetLocationAsync
添加一个取消标记,但我还不知道如何操作。我没有在 GeolocationRequest 旁边看到它:
编辑 2:
我添加了CancellationToken,但是if语句还是没有到达。可能我还没有用好
using System.Threading; // add above
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken cancelToken = source.Token;
var location = await Geolocation.GetLocationAsync(request, cancelToken);
编辑 3:
下图中的断点永远不会触发,这意味着永远不会到达 if 语句。代码以某种方式退出了 try,但没有进入其中一个 catch 语句。我现在在我的 catch 语句中使用 Console.WriteLine()
。我在设备日志中看不到任何内容。我在设备日志中看到的 catch 中测试了 Console.WriteLine()
。
看来,我等的时间不够长。正如杰森所说。
我第一次尝试添加超时是:
new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue);
不知何故上面的行不起作用。
无论如何添加 10 秒的时间跨度给了我一个位置:
var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
在我的情况下,在位置设置下打开 phone 的“提高准确性”选项很有帮助;至少 Android 是这样。