Xamarin - 在 WebView 中请求相机权限
Posted
技术标签:
【中文标题】Xamarin - 在 WebView 中请求相机权限【英文标题】:Xamarin - Requesting camera permissions in WebView 【发布时间】:2020-05-03 09:49:09 【问题描述】:我想为我的 Web 应用程序创建一个容器应用程序,我决定在 Xamarin 中这样做,因为该项目的其余部分也是 .NET。
最初我从 Xamarin 示例页面下载并设置项目: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/webview?tabs=windows
我只是更改了 WebPage.cs 中的一些变量:https://github.com/xamarin/xamarin-forms-samples/blob/master/WorkingWithWebview/WorkingWithWebview/WebPage.cs
using Xamarin.Forms;
namespace WorkingWithWebview
public class WebPage : ContentPage
public WebPage()
var browser = new WebView();
browser.Source = "https://xamarin.swappsdev.net";
Content = browser;
其次,我更新了 App.cs 以满足我的需要:https://github.com/xamarin/xamarin-forms-samples/blob/master/WorkingWithWebview/WorkingWithWebview/App。
using Xamarin.Forms;
namespace WorkingWithWebview
public class App : Application
public App ()
MainPage = new WebPage();
然后繁荣!我有一个应用程序。
然后是真正的斗争。在 Web 应用程序中,当我在浏览器中打开网站 (https://xamarin.swappsdev.net) 时,我可以单击向设备请求权限的按钮,然后在同一窗口中显示摄像头源。
在应用程序中执行相同操作时,没有任何反应。
然后我开始在谷歌上搜索答案,但实际上并没有找到很多答案。我找到的答案似乎是旧版本的 Xamarin (?),因为我无法将答案中的文件和结构与 Xamarin 示例页面中的文件和结构进行比较。 https://***.com/a/50560855
我尝试在这里实现 Robbit 的答案。经过长时间的努力,我设法编译它并将其安装在我的设备上,但它实际上并没有请求权限。
我不知所措,可能需要一些帮助/指导。
【问题讨论】:
希望对您有所帮助,github.com/jamesmontemagno/PermissionsPlugin 【参考方案1】:更新:
在我之前的回答中,它展示了如何在 webview 上添加摄像头权限。
您提供的链接,现在可以使用。 https://xamarin.swappsdev.net/好像提供了相机预览功能。它需要检查 API 23+ 的权限。
在 Xamarin.Forms 上,您可以使用权限插件。 https://github.com/jamesmontemagno/PermissionsPlugin
首先,在 android Manifest 中添加摄像头权限。 您的 Project.Android> 属性> Android 清单> 所需权限> 相机。之后,它会在 AndroidManifest.xml 中生成用户权限。
<uses-permission android:name="android.permission.CAMERA" />
创建一个 Utils.cs。
public static class Utils
public static async Task<PermissionStatus> CheckPermissions(Permission permission)
var permissionStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(permission);
bool request = false;
if (permissionStatus == PermissionStatus.Denied)
if (Device.RuntimePlatform == Device.ios)
var title = $"permission Permission";
var question = $"To use this plugin the permission permission is required. Please go into Settings and turn on permission for the app.";
var positive = "Settings";
var negative = "Maybe Later";
var task = Application.Current?.MainPage?.DisplayAlert(title, question, positive, negative);
if (task == null)
return permissionStatus;
var result = await task;
if (result)
CrossPermissions.Current.OpenAppSettings();
return permissionStatus;
request = true;
if (request || permissionStatus != PermissionStatus.Granted)
var newStatus = await CrossPermissions.Current.RequestPermissionsAsync(permission);
if (!newStatus.ContainsKey(permission))
return permissionStatus;
permissionStatus = newStatus[permission];
if (newStatus[permission] != PermissionStatus.Granted)
permissionStatus = newStatus[permission];
var title = $"permission Permission";
var question = $"To use the plugin the permission permission is required.";
var positive = "Settings";
var negative = "Maybe Later";
var task = Application.Current?.MainPage?.DisplayAlert(title, question, positive, negative);
if (task == null)
return permissionStatus;
var result = await task;
if (result)
CrossPermissions.Current.OpenAppSettings();
return permissionStatus;
return permissionStatus;
在 MainActivity.cs 中,添加 OnCreate 方法中的代码。
Plugin.CurrentActivity.CrossCurrentActivity.Current.Init(this, savedInstanceState);
MainActivity.cs 中需要 OnRequestPermissionsResult。
public override void OnRequestPermissionsResult(int requestCode, string[] permissions,
[GeneratedEnum] Android.Content.PM.Permission[] grantResults)
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
然后实现它。
private async void _button_Clicked(object sender, EventArgs e)
webView.Source = "https://xamarin.swappsdev.net/";//"https://test.webrtc.org/";
var status = PermissionStatus.Unknown;
status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
if (status != PermissionStatus.Granted)
status = await Utils.CheckPermissions(Permission.Camera);
我已在我的 GitHub 上上传。检查文件夹。测试/CameraRuntimePermission_WebView/RuntimePermission
https://github.com/WendyZang/Test.git
编辑:
如果你不想在按钮点击事件中调用它,你可以删除 MainPage.xaml 中的按钮。
MainPage.xaml.cs
public MainPage()
InitializeComponent();
webView.Source = "https://xamarin.swappsdev.net/";
protected override void OnAppearing()
base.OnAppearing();
RunTimePermission();
public async void RunTimePermission()
var status = PermissionStatus.Unknown;
status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
if (status != PermissionStatus.Granted)
status = await Utils.CheckPermissions(Permission.Camera);
【讨论】:
温迪,这太棒了!太感谢了。最后一件事,是否需要单击按钮,或者是否可以在启动应用程序时触发权限请求或有某种启动画面? 不可以,没有按钮也可以加载,但是需要在页面加载后询问运行时权限。我在编辑中提供了代码。 我并不自豪承认这一点,但我错过了您将webView.Source = "https://xamarin.swappsdev.net/";
移动到构造函数中的部分。我花了一段时间才弄清楚为什么我只是在看一个白屏,但除此之外它就可以工作。非常感谢您的帮助和时间!!【参考方案2】:
我尝试在这里实现 Robbit 的答案。经过长时间的努力,我设法编译它并将其安装在我的设备上,但它实际上并没有请求权限。
我尝试了 Robbit 从链接中提供的代码。Camera on Xamarin WebView
实际上,它运作良好。为了更好地理解,您可以使用下面的链接进行检查。 https://test.webrtc.org/
如果我使用 webview 直接加载 url,它会抛出如下错误。
如果我使用 Robbit 的自定义渲染器,它会请求 MyWebViewRenderer 中代码的许可。
public override void OnPermissionRequest(PermissionRequest request)
mContext.RunOnUiThread(() =>
request.Grant(request.GetResources());
);
我也检查了你使用的链接,没有发生任何事情。该链接无法在 Android 设备中打开相机。
使用 Robbit 的代码。
在您的项目中创建 MyWebView。
public class MyWebView : WebView
在项目的 Android 部分中创建 MyWebViewRenderer.cs。
[assembly: ExportRenderer(typeof(MyWebView), typeof(MyWebViewRenderer))]
namespace WebViewDemo.Droid
public class MyWebViewRenderer : WebViewRenderer
Activity mContext;
public MyWebViewRenderer(Context context) : base(context)
this.mContext = context as Activity;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
base.OnElementChanged(e);
Control.Settings.javascriptEnabled = true;
Control.ClearCache(true);
Control.SetWebChromeClient(new MyWebClient(mContext));
public class MyWebClient : WebChromeClient
Activity mContext;
public MyWebClient(Activity context)
this.mContext = context;
[TargetApi(Value = 21)]
public override void OnPermissionRequest(PermissionRequest request)
mContext.RunOnUiThread(() =>
request.Grant(request.GetResources());
);
用法:
MainPage.xaml
<StackLayout>
<Button x:Name="_button" Clicked="_button_Clicked" />
<local:MyWebView
x:Name="webView"
HeightRequest="500"
WidthRequest="500" />
</StackLayout>
MainPage.xaml.cs
private void _button_Clicked(object sender, EventArgs e)
webView.Source = "https://test.webrtc.org/";//"https://xamarin.swappsdev.net/";
您可以从 GitHub 文件夹 CameraRuntimePermission_WebView
下载整个项目。 Page1 用于测试与 webview 的链接。 MainPage 用于使用自定义渲染器进行测试。
https://github.com/WendyZang/Test.git
【讨论】:
您好,Wendy,非常感谢您非常详细的回复。但是,我仍然遇到同样的旧权限问题。我在您的“CameraRuntimePermission_WebView”项目中加载并尝试在不进行任何修改的情况下运行它。它编译得很好,并向我显示了您在 gif 中显示的空白按钮,但它也告诉我它无法访问 webrtc-test 中所需的硬件。之后我尝试使用自己的链接:这是我在自己的链接上运行它时的日志。 pastebin.com/3c9nKsTd 这是我通常会面朝前撞墙的地方。它从不请求权限。 我已经修复了错误,我需要一些时间来编辑我的回复。请稍等。 感谢您抽出宝贵的时间撰写此答案。非常感谢!!它按预期工作..【参考方案3】:按照几个指南启用WebView的摄像头,我终于成功了。
我按照上述所有步骤操作,尽管收到允许使用相机的提示,但我始终无法摆脱权限错误(即使调试显示权限已被授予)。然后我将 MyWebViewRenderer 代码(Wendy 上面给出的)替换为以下代码(如 https://forums.xamarin.com/discussion/183988/how-to-give-camera-and-microphone-permission-to-webview-with-xamarin-forms-on-android 给出的):
[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace App19F_8.Droid
public class CustomWebViewRenderer : WebViewRenderer
public CustomWebViewRenderer(Context context) : base(context)
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
base.OnElementChanged(e);
if (e.NewElement != null)
Control.SetWebChromeClient(new MyWebChromeClient(MainActivity.Instance));
Control.Settings.JavaScriptEnabled = true;
public class MyWebChromeClient : WebChromeClient
Activity mActivity = null;
public MyWebChromeClient(Activity activity)
mActivity = activity;
public override void OnPermissionRequest(PermissionRequest request)
mActivity.RunOnUiThread(() =>
request.Grant(request.GetResources());
);
如果上面的链接失效,我应该提一下,在 Android 的 MainActivity 中你应该插入以下内容:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
public static MainActivity Instance get; private set;
protected override void OnCreate(Bundle savedInstanceState)
...
base.OnCreate(savedInstanceState);
Instance = this;
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
现在摄像头终于开始工作了 :-) 我不确定之前代码中的罪魁祸首是什么。非常感谢 Wendy、Yelinzh 和所有人的彻底回复。
【讨论】:
感谢您的意见!您永远不知道此信息何时变得相关,因此感谢您抽出宝贵时间来编译此答案。 它按预期工作。感谢您抽出宝贵的时间来写这个答案。能否请您告诉我 ios 是否需要任何类似的程序? @Thameem - 很抱歉回复很晚 - 不幸的是,我还没有在 iOS 上测试过这个 - 只有 Android。希望你来对了... 有效!!值得一提的是,它需要创建一个 CustomWebView 并像这里提到的那样使用它:docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/…以上是关于Xamarin - 在 WebView 中请求相机权限的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Forms WebView 不适用于 WebRTC
Xamarin.Forms webview 进行身份验证,导航到新页面(Shell)并需要再次重新验证?