MAUI Blazor 和 WebView 脱不了干系
前言
由于MAUI Blazor和原生的MAUI不一样,MAUI Blazor是嵌套webview实现的,页面是Razor组件组成;我们在申请设备权限的适合,必须向webview申请权限;
整理此文的目的是为了保留这一技术栈,网络上关于MAUI Blazor 混合开发的参考点太少了,给后辈提供参考价值
文中提到的Html代码块其实也可以运用在Vue中,Vue发布编译后也是可以通过核心文件MauiWebChromeClient来赋予页面权限的,可以不局限于最新的MAUI框架+razor文件实现,有了更多的可拓展性和灵活性
但是混合开发的缺点就是关于资源损耗等性能方面的问题还有待考究,还望后辈慎重考虑使用混合开发的形式,毕竟这种开发虽然灵活,同时也对你的资源管控有着很高的要求
1.修改AndroidManifest.xml
修改PlatformsAndroidAndroidManifest.xml
<!--相机权限-->
<uses-permission android:name="android.permission.CAMERA" android:required="false"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--相机功能-->
<uses-feature android:name="android.hardware.camera" />
<!--音频录制权限-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!--位置权限-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
<uses-feature android:name="android.hardware.location.gps" />
2.修改MainActivity.cs
修改PlatformsAndroidMainActivity.cs;重写OnCreate方法,申请权限;
public class MainActivity : MauiAppCompatActivity
{
/// <summary>
/// 需要申请的权限列表
/// </summary>
private readonly List<string> _permissions = new()
{
Manifest.Permission.Camera,
Manifest.Permission.RecordAudio,
Manifest.Permission.ModifyAudioSettings,
// 蓝牙需要的权限
Manifest.Permission.BluetoothScan,
Manifest.Permission.AccessCoarseLocation,
Manifest.Permission.AccessFineLocation,
Manifest.Permission.BluetoothConnect
};
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Platform.Init(this, savedInstanceState);
ActivityCompat.RequestPermissions(this, _permissions.ToArray(), 0);
}
}
3.自定义MauiWebChromeClient类
这个类很重要,运行原理是在你注解后,程序/APP运行到混合开发页面中时,自动索取权限的过程
下面的是我参考网络匿名大佬写的自定义类二次封装的,可以根据实际情况变动
#if ANDROID
using Android.Webkit;
using Microsoft.AspNetCore.Components.WebView.Maui;
namespace XXXXXXX;
public class MauiWebChromeClient : WebChromeClient
{
public override void OnPermissionRequest(PermissionRequest request)
{
// 处理每个请求
foreach (var resource in request.GetResources())
{
// 检查网页是否正在请求对相机的权限
if (resource.Equals(PermissionRequest.ResourceVideoCapture, StringComparison.OrdinalIgnoreCase))
{
// 检查网页是否正在请求对相机的权限
PermissionStatus status = Permissions.CheckStatusAsync<Permissions.Camera>().Result;
// 如果应用程序对摄像头的访问权限未“授予”,则拒绝网页的请求
if (status != PermissionStatus.Granted)
request.Deny();
else
request.Grant(request.GetResources());
return;
}
}
request.Grant(request.GetResources());
}
}
public class MauiBlazorWebViewHandler : BlazorWebViewHandler
{
protected override void ConnectHandler(Android.Webkit.WebView platformView)
{
platformView.SetWebChromeClient(new MauiWebChromeClient());
base.ConnectHandler(platformView);
}
}
#endif
参考灵感
#if ANDROID
using Android.Webkit;
using Microsoft.AspNetCore.Components.WebView.Maui;
namespace Master.app;
public class MauiWebChromeClient : WebChromeClient
{
public override void OnPermissionRequest(PermissionRequest request)
{
request.Grant(request.GetResources());
}
}
public class MauiBlazorWebViewHandler : BlazorWebViewHandler
{
protected override void ConnectHandler(Android.Webkit.WebView platformView)
{
platformView.SetWebChromeClient(new MauiWebChromeClient());
base.ConnectHandler(platformView);
}
}
#endif
4.MauiProgram.cs
注意一定要写在 builder.Services.AddMauiBlazorWebView()之后
注意一定要写在 builder.Services.AddMauiBlazorWebView()之后
注意一定要写在 builder.Services.AddMauiBlazorWebView()之后
#if ANDROID是必须要加的,这个东西是只有在Android环境下运行的
#if ANDROID
builder.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler<IBlazorWebView, MauiBlazorWebViewHandler>();
});
#endif
5.添加nuget包ZXingBlazor 1.01版本
6.Index.razor添加扫码组件
<Button OnClick="(()=>ShowScanBarcode=!ShowScanBarcode)">扫码</Button>
<span class="text-success h5 fw-bold">@Barcode</span>
@if (ShowScanBarcode)
{
<ZXingBlazor.Components.BarcodeReader ScanResult="((e)=>{Barcode=e;ShowScanBarcode=!ShowScanBarcode;})" Close="(()=>ShowScanBarcode=!ShowScanBarcode)">
</ZXingBlazor.Components.BarcodeReader>
}
@code{
private bool ShowScanBarcode;
public string Barcode { get; set; }
}
7.效果图