Xamarin Android WebView的ShouldOverrideUrlLoading未触发回调求助
解决方案:在Xamarin Android WebView中拦截自定义Scheme回调(KitKat+)
你遇到的问题确实是Android KitKat(API 19)之后WebView的行为变更导致的——旧版的ShouldOverrideUrlLoading(string url)只会拦截HTTP/HTTPS协议的URL,自定义Scheme(比如io.identitymodel.native://callback)的跳转不会触发这个方法。下面是针对KitKat及以上版本的可行解决方案:
1. 重写WebViewClient的新版ShouldOverrideUrlLoading方法
从API 24开始,Android提供了带IWebResourceRequest参数的重载方法,这个方法会触发所有类型的URL跳转,包括自定义Scheme。同时为了兼容API 19-23,我们需要同时处理两个重载:
public class CustomWebViewClient : WebViewClient { private readonly Context _context; public CustomWebViewClient(Context context) { _context = context; } // 兼容API 24+ public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request) { var url = request.Url.ToString(); return HandleCustomSchemeUrl(url); } // 兼容API 19-23 public override bool ShouldOverrideUrlLoading(WebView view, string url) { return HandleCustomSchemeUrl(url); } private bool HandleCustomSchemeUrl(string url) { // 检测是否是目标自定义Scheme回调 if (url.StartsWith("io.identitymodel.native://callback")) { // 解析URL中的OIDC所需参数(比如code、state) var uri = Android.Net.Uri.Parse(url); var authCode = uri.GetQueryParameter("code"); var state = uri.GetQueryParameter("state"); // 启动目标Activity并传递参数 var intent = new Intent(_context, typeof(YourCallbackActivity)); intent.PutExtra("auth_code", authCode); intent.PutExtra("state", state); _context.StartActivity(intent); // 返回true表示拦截该URL,不再由WebView加载 return true; } // 非目标URL,交给WebView正常处理 return false; } }
2. 配置WebView的必要设置
确保你的WebView允许加载自定义Scheme,并且启用JavaScript(OIDC流程通常需要JS支持):
var webView = FindViewById<WebView>(Resource.Id.webview); webView.Settings.JavaScriptEnabled = true; webView.Settings.AllowFileAccess = true; // 设置自定义WebViewClient webView.SetWebViewClient(new CustomWebViewClient(this)); // 加载OIDC授权页面 webView.LoadUrl("https://your-oidc-provider.com/authorize?client_id=xxx&response_type=code&redirect_uri=io.identitymodel.native://callback&scope=openid");
3. 注册回调Activity的Scheme过滤(可选但推荐)
为了让系统明确识别你的Activity处理该自定义Scheme,在AndroidManifest.xml中为YourCallbackActivity添加intent-filter:
<activity android:name=".YourCallbackActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 指定处理的自定义Scheme --> <data android:scheme="io.identitymodel.native" /> </intent-filter> </activity>
这样即使后续有其他场景触发该Scheme跳转,系统也会正确路由到你的Activity,同时也能让WebView更准确地识别该Scheme的跳转需要被拦截。
关键注意点
- 一定要同时实现两个
ShouldOverrideUrlLoading重载,覆盖API 19到最新版本的设备 - 处理URL时要确保正确解析OIDC所需的参数(比如code、state),避免遗漏
- 如果你的OIDC流程涉及到HTTPS页面的跳转,要确保WebView信任对应的证书(如果是自签名证书,需要额外配置证书验证)
内容的提问来源于stack exchange,提问作者rideintothesun
相关产品推荐
相关产品推荐

