I have an MAUI app that is essentially a WebView
that hosts a wordpress website.
My problem is that whenever I try to load an external link it will simply not load the "href" redirect... It works fine on Windows and iOS devices, but not in android.
EDIT: The href is a "_blank" target.
Is there a specific permission I need in the manifest?
In case it helps, here is the code for the page:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MYAPPNAME.EnglishPage"
NavigationPage.HasNavigationBar="False" NavigationPage.HasBackButton="False"
Shell.NavBarIsVisible="False">
<Grid BackgroundColor="DarkSlateGrey">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" Grid.Column="0"
Spacing="5" Orientation="Horizontal" Padding="8">
<Button Text="Go Back" TextColor="DarkSlateGray" BackgroundColor="White"/>
<Button Text="Change Language" x:Name="ChangeLangBtn" TextColor="DarkSlateGray" BackgroundColor="White"/>
</StackLayout>
<WebView Grid.Row="1" Grid.Column="0"
Source="https://example.com"
x:Name="WebView"/>
</Grid>
</ContentPage>
And here is the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="2" android:versionName="2">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true" android:label="MYAPPNAME"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
</manifest>
CodePudding user response:
I have done a sample to test the webview in the android, it can open the href in the website successfully.
So you can check the href you want open is http or not. For the android api higher than 27, you need to declare the android:usesCleartextTraffic
as true in the AndroidManifest.xml, such as:
<manifest ...>
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
You can also try to load another website in your webview to test.
CodePudding user response:
So to handle redirects to _blank
targets in a WebView by keeping them in the same window/view, I had to create a custom renderer, but don't worry, you can just copy-paste the code and it will work perfectly :) .
- Create a folder called
Controls
insidePlatforms/Android
, then create a class file, I called itMltWebViewClientRenderer.cs
. Paste this inside the file:
public class MltWebViewRenderer : WebViewRenderer
{
public MltWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Microsoft.Maui.Controls.WebView> e)
{
base.OnElementChanged(e);
Control.SetWebViewClient(new MltWebViewClient());
global::Android.Webkit.WebView.SetWebContentsDebuggingEnabled(true);
}
}
public class MltWebViewClient : global::Android.Webkit.WebViewClient
{
public MltWebViewClient()
{
}
public override bool ShouldOverrideUrlLoading(global::Android.Webkit.WebView view, IWebResourceRequest request)
{
view.Settings.SetSupportMultipleWindows(false);
view.Settings.JavaScriptCanOpenWindowsAutomatically = true;
view.Settings.JavaScriptEnabled = true;
view.SetWebChromeClient(new WebChromeClient());
return base.ShouldOverrideUrlLoading(view, request);
}
}
The above code basically allows access to the Settings
of the WebView
.
- In the
MauiProgram.cs
, you need to add some services to the builder, as such:
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.UseMauiCompatibility()
.ConfigureMauiHandlers(x =>
{
#if ANDROID
x.AddCompatibilityRenderer(typeof(WebView), typeof(Platforms.Android.Controls.MltWebViewRenderer));
#endif
});
return builder.Build();
The above only invokes our custom renderer if we are on Android.
Note: This solution only works for Android API versions 24 and above.