Xamarin Forms WebView加载嵌入Google Maps网页报Permission denied错误
这个Permission denied报错和你配的网络安全规则、申请的清单权限、引入的Google Play Services地图包都没关系。核心原因是Android原生WebView默认关闭了大量H5运行需要的特性,Xamarin.Forms封装的默认WebView渲染器也没有主动开启这些配置:包括JavaScript执行权限、DOM本地存储、地理位置权限回调处理都是默认禁用的。系统浏览器默认会开启这些配置,所以会出现浏览器打开正常、App内WebView报错的现象。你加的Xamarin.GooglePlayServices.Maps是给原生地图控件用的,对WebView加载的H5地图完全无效,可以直接移除。
1. 清理冗余配置
你之前写的网络安全配置没必要单独给Google系域名加规则,直接简化成下面的内容就行,避免规则冲突:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config> </network-security-config>
清单里声明的网络、位置权限是对的,不需要额外新增其他权限。
2. 自定义Android端WebView渲染器
在你的Android项目里新增自定义WebView渲染器,开启WebView默认关闭的必要配置,同时处理H5发起的权限请求:
using Android.Webkit; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; // 替换成你自己的Android项目命名空间 using YourApp.Droid; [assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))] namespace YourApp.Droid { public class CustomWebViewRenderer : WebViewRenderer { public CustomWebViewRenderer(Android.Content.Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<WebView> e) { base.OnElementChanged(e); if (Control == null) return; // 开启Google Maps运行必须的配置 var settings = Control.Settings; settings.JavaScriptEnabled = true; settings.DomStorageEnabled = true; // 必开,Google Maps依赖DOM存储存配置 settings.SetGeolocationEnabled(true); settings.DatabaseEnabled = true; settings.AllowFileAccess = true; settings.AllowContentAccess = true; settings.CacheMode = CacheModes.Normal; // 挂载自定义ChromeClient处理H5权限请求 Control.SetWebChromeClient(new MapWebChromeClient()); } } public class MapWebChromeClient : WebChromeClient { public override void OnGeolocationPermissionsShowPrompt(string origin, GeolocationPermissions.ICallback callback) { // 这里可以加域名白名单判断,直接允许对应域名的位置请求 callback.Invoke(origin, true, false); } } }
如果你的App目标SDK版本是23及以上(也就是Android 6.0+),必须在页面加载前动态申请
ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION运行时权限,系统层面拦截位置请求的话,WebView里的地图一样会报权限错误。
3. 混合内容适配(可选)
如果你的站点存在HTTP资源和HTTPS页面混合加载的情况,在上面的WebSettings配置里额外加一行:
settings.MixedContentMode = MixedContentHandling.AlwaysAllow;
改完之后重新全量编译部署,不要用VS的快速部署模式测试,打完整的Debug或Release包安装,地图就能正常加载。
- 先确认你的H5页面在手机端Chrome浏览器里打开完全正常,排除页面本身的代码问题
- 如果还是报错,可以打开WebView远程调试,电脑Chrome打开
chrome://inspect找到App里对应的WebView页面,看控制台具体报错的位置,对应调整配置即可 - 如果你的页面用了Google Maps的定位功能,记得在H5代码里判断定位失败的兜底逻辑,不要因为定位拿不到导致整个地图渲染失败
内容的提问来源于stack exchange,提问作者Aishwarya Shiva

