Camera on Xamarin WebView

2020-07-23 09:42发布

问题:

I have a simple Xamarin Page with a WebView that calls a WebRTC test page:

        _webView = new WebView
        {
            Source = "https://test.webrtc.org/",
            WidthRequest = 1000,
            HeightRequest = 1000
        };

        var stackLayout = new StackLayout()
        {
            Orientation = StackOrientation.Vertical,
            Padding = new Thickness(5, 20, 5, 10),
            Children = { _webView }
        };

        Content = new StackLayout { Children = { stackLayout } };

The https://test.webrtc.org/ page works fine on Chrome on the same Android Emulator, but don't work on WebView saying "NotAllowedError".

The application have the required permissions. The following code (that use Plugin.Permissions) returns true:

var statusCamera = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
var statusMicrophone = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Microphone);
return statusCamera == PermissionStatus.Granted && statusMicrophone == PermissionStatus.Granted;

What's wrong?

Thanks

回答1:

About NotAllowedError, from here:

The user has specified that the current browsing instance is not permitted access to the device; or the user has denied access for the current session; or the user has denied all access to user media devices globally.


You need custom a WebView to override the WebChromeClient's OnPermissionRequest method.

MyWebView class in PCL:

public class MyWebView: WebView
{
}

MyWebViewRenderer and MyWebClient class:

[assembly: ExportRenderer(typeof(App45.MyWebView), typeof(MyWebViewRenderer))]
namespace App45.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());

                        });

            }
        }

    }

}

Here, I have provided a demo for you to test. The camera should work for you.