.NET MAUI Android模拟器中Geolocation.Default.GetLocationAsync()调用后挂起
问题描述
已在AndroidManifest.xml中添加如下配置:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true" android:usesCleartextTraffic="true"> <meta-data android:name="com.google.android.geo.API_KEY" android:value="12345" /> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> </application> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_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" /> </manifest>
运行以下定位代码时:
try { _isCheckingLocation = true; GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10)); _cancelTokenSource = new CancellationTokenSource(); Location location = await Geolocation.Default.GetLocationAsync(request, _cancelTokenSource.Token); if (location != null) { Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}"); return location; } } // Catch one of the following exceptions: // FeatureNotSupportedException // FeatureNotEnabledException // PermissionException catch (FeatureNotSupportedException fnsEx) { // Handle not supported on device exception err = fnsEx.Message; } catch (FeatureNotEnabledException fneEx) { // Handle not enabled on device exception err = fneEx.Message; } catch (PermissionException pEx) { // Handle permission exception err = pEx.Message; } catch (Exception ex) { // Unable to get location err = ex.Message; } finally { _isCheckingLocation = false; }
模拟器弹出定位权限请求,点击允许后,调试流程无返回、无任何错误抛出,程序陷入无响应状态。
解决方案
- 补全动态权限申请:Android 6.0+仅在Manifest声明权限不够,需在调用定位前主动请求权限。执行
await Permissions.RequestAsync<Permissions.LocationWhenInUse>(),确认返回PermissionStatus.Granted后再调用GetLocationAsync。 - 设置模拟器模拟位置:部分模拟器默认无定位数据,需手动在模拟器的定位设置中添加模拟坐标,或用ADB命令注入:
adb shell am set-location 39.904200 116.407400 - 调整定位参数:尝试降低精度(比如
GeolocationAccuracy.Low)并缩短超时时间,避免模拟器因无法快速获取高精度位置导致阻塞。 - 排查主线程死锁:确保调用该定位方法的上层函数标记为
async,避免使用.Result或.Wait()同步等待,防止主线程被阻塞。 - 验证Google Play服务:模拟器需安装对应版本的Google Play服务,可在模拟器设置中检查服务状态,定位依赖该服务正常运行。
- 强化取消逻辑:可在超时后手动触发
_cancelTokenSource.Cancel(),确保即使定位无响应也能终止等待流程。
内容的提问来源于stack exchange,提问作者Cef
相关产品推荐
相关产品推荐

