maui
maui copied to clipboard
Android WebViewClient's ShouldInterceptRequest is never called in MAUI WebView
Description
Android WebViewClient
's ShouldInterceptRequest
is never called in MAUI WebView
Steps to Reproduce
1.create a maui demo;
2.copy the following code to MauiProgram.cs
:
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler<Microsoft.Maui.Controls.WebView, ProblemHandler2>();
});
return builder.Build();
}
}
internal class ProblemHandler1 : WebViewHandler
{
protected override Android.Webkit.WebView CreatePlatformView()
{
var wv = base.CreatePlatformView();
wv.SetWebViewClient(new CustomWebClient());
return wv;
}
}
internal class ProblemHandler2 : WebViewHandler
{
protected override Android.Webkit.WebView CreatePlatformView()
{
var wv = new Android.Webkit.WebView(Android.App.Application.Context);
wv.SetWebViewClient(new CustomWebClient());
return wv;
}
}
internal class CustomWebClient : WebViewClient
{
public override WebResourceResponse ShouldInterceptRequest(Android.Webkit.WebView view, IWebResourceRequest request)
{
Debugger.Break();
Debug.WriteLine(request.Url.ToString());
return base.ShouldInterceptRequest(view, request);
}
}
MainPage.xaml.cs
public partial class MainPage : ContentPage
{
int count = 0;
public MainPage()
{
InitializeComponent();
WebViewHandler.Mapper.AppendToMapping("MyHandler", (handler, view) =>
{
#if ANDROID
var xWv = handler.PlatformView;
// For ProblemHandler2, this is needed to actually navigate:
xWv.LoadUrl("https://www.google.com/");
#endif
});
this.wv.Source = "https://www.google.com/";
}
}
3.build and deploy this demo to android device. (I only tested on android 13 emulator )
Link to public reproduction project repository
https://github.com/datvm/DemoMauiWvClient
Version with bug
Unknown/Other (please specify)
Last version that worked well
Unknown/Other
Affected platforms
Android, I was not able test on other platforms
Affected platform versions
Android 13
Did you find any workaround?
No response
Relevant log output
No response
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
Hi @hartez , is there any workaround ?
WebViewClient.OnPageFinished(Android.Webkit.WebView platformView, string url) is NOT being called as well.
@ederbond you are correct. This issue was created from this question on StackOverflow (by me), and I tried a few other callbacks as well. I suspect none of them is called.
Hi any update on this? This is very important because without it, we cannot load local HTML content in our app following the official Android guide
Hi @jessiezh0320 @hartez Would you have any idea when this is likely to be fixed, or a workaround? Thank you
@hartez @davidortinau @jsuarezruiz @maddymontaquila any due date about this? It totally prevents me to ship my MAUI app without this fixed.
Still no reply from the team about this. It would be nice to at least get a rough timeline for a fix. 1 month, 6 months, longer??
Any news about it? This is a very big issue, we cannot ship the app without this fix.
I'm being blocked to ship my app too. Any news @jsuarezruiz or @hartez @StephaneDelcroix @PureWeen @rmarinho @davidortinau @maddymontaquila about this?
Btw in the mean time, can anyone check their source code and see how they fix it for their MAUI Blazor? I think their MAUI Blazor uses a customized WebView as well and intercept the https://0.0.0.0
. Maybe we can use that workaround in the mean time?
UPDATE: It's here, ~~they use WebChromeClient
so it's irrelevant~~ they use a custom WebViewHandler defined here WebViewHandler.Android.cs. No idea why it works for them though. Can someone investigate?
Whoever would work on this issue, please also make sure WebViewClient.OnPageFinished(Android.Webkit.WebView platformView, string url) will be called properly as well.
Any news about this? More than a month passed and still no clues about when this will be fixed
Hey sorry just get back to this now, you should override the specific mapper we added for this: https://github.com/dotnet/maui/blob/main/src/Core/src/Handlers/WebView/WebViewHandler.cs#L28
Microsoft.Maui.Handlers.WebViewHandler.ModifyMapping(nameof(WebViewClient), (handler, view) =>
{
handler.PlatformView.SetWebViewClient(new CustomWebClient());
});
Sorry I gave up on this a long time ago and just use the MAUI Blazor. Can anyone confirm this is fixed?
@jessiezh0320 can you try it out?
Microsoft.Maui.Handlers.WebViewHandler.ModifyMapping(nameof(WebViewClient), (handler, view) => { handler.PlatformView.SetWebViewClient(new CustomWebClient()); });
@rmarinho please correct me, but WebViewHandler does not contain such method (or extension).
On the other hand the static PropertyMapper in WebViewHandler has an extension method with the name of ModifyMapping, but with a different signature. Unfortunately calling this method did not solve the issue.
#if ANDROID
WebViewHandler.Mapper.ModifyMapping(nameof(Android.Webkit.WebViewClient), (handler, view, setter) =>
{
handler.PlatformView.SetWebViewClient(new CustomWebClient());
});
#endif
Maybe one has to provide a custom setter?
@rmarinho I've tried also on my side the suggested workaround and as said by @mihaly-bence16 the signature of the method is different. Even so it does not work. So any updates regarding this?
Found this accidently thinking I had coded something incorrectly but every single guide online says this is the way to handle SSL/TLS certificate errors. Can confirm that the constructor of the WebViewClient is called but none of these are:
- ShouldOverrideUrlLoading(WebView, IWebResourceRequest)
- ShouldOverrideUrlLoading(WebView, string)
- WebResourceResponse ShouldInterceptRequest(WebView, IWebResourceRequest)
- OnReceivedSslError(WebView, SslErrorHandler, SslError)
- OnReceivedError(WebView, IWebResourceRequest, WebResourceError)
- OnPageStarted(WebView, string, Bitmap)
- OnPageFinished(WebView, string)
I overrode EVERY possible method and put breakpoints in them. None of them were hit.
I tried the work-around mentioned above, it does not work!
//DOES NOT WORK!
Microsoft.Maui.Handlers.WebViewHandler.Mapper.ModifyMapping(nameof(global::Android.Webkit.WebViewClient), (handler, view, setter) =>
{
handler.PlatformView.SetWebViewClient(new DweWebViewClient());
});
Hopefully this helps anyone running into this issue. I got it working after some poking around in the debugger. Added this below into my MauiProgram.cs and in 'platforms/Android' have my CustomWebviewClient with the overrides for the following below.
-
WebResourceResponse ShouldInterceptRequest(WebView, IWebResourceRequest)
-
OnReceivedSslError(WebView, SslErrorHandler, SslError)
#If ANDROID Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping(nameof(Android.Webkit.WebViewClient), (handler, view) => { handler.PlatformView.SetWebViewClient(new CustomWebViewClient()); }); #endif
Well... This partially works... I added this to my MauiBuilderExtensions and my custom WebViewClient starts working! Yay!
Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping(
nameof(global::Android.Webkit.WebViewClient),
(handler, _) => handler.PlatformView.SetWebViewClient(new DweWebViewClient()));
But that then breaks my code that hooks up to the WebView.Navigated event! Boo! The event simply does not fire. I have checked the order of execution and the setting of the WebViewClient is happening before the += to the Navigated event.
So we're back to square one in need of a fix
UPDATE: I have managed to get the work-around functional! I changed my custom WebViewClient to inherit from MauiWebViewClient (instead of WebViewClient) and updated the code in my MauiAppBuilderExtensions to be:
Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping(
nameof(global::Android.Webkit.WebViewClient),
(handler, _) => handler.PlatformView.SetWebViewClient(new DweWebViewClient((Microsoft.Maui.Handlers.WebViewHandler)handler)));
This seems to work as the OnReceivedSslError() method is now being hit and the WebView.Navigated event is being fired too.
NOTE: This AppendToMapping work-around also seems to work for SetWebChromeClient() as that is now working for me too
I wonder why ModifyMapper doens't work
@rmarinho I'm not fully sure why either without spending some more time debugging, but when using ModifyMapping my new CustomWebviewClient is being set in SetWebviewClient. Though non of the override methods are being called. There might be some form of order of operations going on.
I think I found out why:
public static void MapWebViewClient(IWebViewHandler handler, IWebView webView)
{
if (handler is WebViewHandler platformHandler)
handler.PlatformView.SetWebViewClient(platformHandler._webViewClient ??= new MauiWebViewClient(platformHandler));
}
The existing mapper would set a field in the handler and use that in other places. Let me see if there is a better way we can do this to avoid the field or at least retrieve the client you set.