Xamarin Android Webview:getUserMedia 无法打开相机
Xamarin Android Webview: getUserMedia fails to open camera
我正在尝试打开相机并允许用户从 Xamarin.Android 的网络视图中捕捉图像帧。
我已将 webview 指向此 URL,其中包含几个示例:https://googlechrome.github.io/samples/image-capture/index.html。在设备的 Chrome 浏览器中打开 URL 时,示例可以完美运行,但在应用程序的网络视图中打开时会失败。这是我的网络Chrome客户端实现:
internal class ChromeWebviewClient : WebChromeClient
{
public override void OnPermissionRequest(PermissionRequest request)
{
request.Grant(request.GetResources());
}
}
我在清单中声明了相机权限:
<uses-permission android:name="android.permission.CAMERA" />
导航到示例页面并点击“获取用户媒体”似乎没有任何作用,我在应用程序日志中看到以下似乎相关但对我来说没有意义的内容:
[CameraManagerGlobal] Connecting to camera service
[VendorTagDescriptor] addVendorDescriptor: vendor tag id 3854507339 added
[CameraManagerGlobal] Camera 0 facing CAMERA_FACING_BACK state now CAMERA_STATE_CLOSED for client com.masterappstudio.qrcodereader API Level 1
[CameraManagerGlobal] Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_CLOSED for client com.sec.android.app.sbrowser API Level 2
[CameraManagerGlobal] Camera 2 facing CAMERA_FACING_FRONT state now CAMERA_STATE_CLOSED for client android.system API Level 2
[CameraManagerGlobal] Camera 90 facing CAMERA_FACING_FRONT state now CAMERA_STATE_CLOSED for client com.samsung.android.server.iris API Level 2
我还在 OnPermissionRequest 下了一个断点,但它似乎没有触发。
我怀疑这与 Android 6+ 中引入的运行时相机权限有关(我是 运行 Android 9)。我已经在 phone 设置中将相机权限设置为允许,但似乎也没有做任何事情。
我已经用尽了 Google 关于这个主题的搜索(大多数点击都围绕着标志性和 phonegap 框架)并注意到这里有几个关于原生 Android 的问题此问题有 0 个答案。
首先,在AndroidManifeast.xml
中添加这些权限
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
如果在Android 6.0 或更高版本上部署应用程序,需要在运行时请求权限。
private void checkpermission()
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) == (int)Permission.Granted)
{
// We have permission, go ahead and use the camera.
}
else
{
// Camera permission is not granted. If necessary display rationale & request.
ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.Camera }, 1);
}
}
要加载一个 URL,子类 Android.Webkit.WebViewClient 并覆盖 ShouldOverriderUrlLoading 方法。
public class HelloWebViewClient : WebViewClient
{
// For API level 24 and later
public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)
{
view.LoadUrl(request.Url.ToString());
return false;
}
}
然后创建自定义 WebChromeClient 以覆盖 OnPermissionRequest 方法以授予请求。
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());
});
}
}
public class MainActivity : AppCompatActivity
{
private WebView webview1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
webview1 = FindViewById<WebView>(Resource.Id.webView1);
webview1.Settings.JavaScriptEnabled = true;
webview1.Settings.AllowFileAccessFromFileURLs = true;
webview1.Settings.AllowUniversalAccessFromFileURLs = true;
webview1.SetWebViewClient(new HelloWebViewClient());
webview1.SetWebChromeClient(new MyWebChromeClient(this));
checkpermission();
}
private void checkpermission()
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) == (int)Permission.Granted)
{
// We have permission, go ahead and use the camera.
webview1.LoadUrl("https://googlechrome.github.io/samples/image-capture/index.html");
}
else
{
// Camera permission is not granted. If necessary display rationale & request.
ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.Camera }, 1);
webview1.LoadUrl("https://googlechrome.github.io/samples/image-capture/index.html");
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
我正在尝试打开相机并允许用户从 Xamarin.Android 的网络视图中捕捉图像帧。
我已将 webview 指向此 URL,其中包含几个示例:https://googlechrome.github.io/samples/image-capture/index.html。在设备的 Chrome 浏览器中打开 URL 时,示例可以完美运行,但在应用程序的网络视图中打开时会失败。这是我的网络Chrome客户端实现:
internal class ChromeWebviewClient : WebChromeClient
{
public override void OnPermissionRequest(PermissionRequest request)
{
request.Grant(request.GetResources());
}
}
我在清单中声明了相机权限:
<uses-permission android:name="android.permission.CAMERA" />
导航到示例页面并点击“获取用户媒体”似乎没有任何作用,我在应用程序日志中看到以下似乎相关但对我来说没有意义的内容:
[CameraManagerGlobal] Connecting to camera service
[VendorTagDescriptor] addVendorDescriptor: vendor tag id 3854507339 added
[CameraManagerGlobal] Camera 0 facing CAMERA_FACING_BACK state now CAMERA_STATE_CLOSED for client com.masterappstudio.qrcodereader API Level 1
[CameraManagerGlobal] Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_CLOSED for client com.sec.android.app.sbrowser API Level 2
[CameraManagerGlobal] Camera 2 facing CAMERA_FACING_FRONT state now CAMERA_STATE_CLOSED for client android.system API Level 2
[CameraManagerGlobal] Camera 90 facing CAMERA_FACING_FRONT state now CAMERA_STATE_CLOSED for client com.samsung.android.server.iris API Level 2
我还在 OnPermissionRequest 下了一个断点,但它似乎没有触发。
我怀疑这与 Android 6+ 中引入的运行时相机权限有关(我是 运行 Android 9)。我已经在 phone 设置中将相机权限设置为允许,但似乎也没有做任何事情。
我已经用尽了 Google 关于这个主题的搜索(大多数点击都围绕着标志性和 phonegap 框架)并注意到这里有几个关于原生 Android 的问题此问题有 0 个答案。
首先,在AndroidManifeast.xml
中添加这些权限<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
如果在Android 6.0 或更高版本上部署应用程序,需要在运行时请求权限。
private void checkpermission()
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) == (int)Permission.Granted)
{
// We have permission, go ahead and use the camera.
}
else
{
// Camera permission is not granted. If necessary display rationale & request.
ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.Camera }, 1);
}
}
要加载一个 URL,子类 Android.Webkit.WebViewClient 并覆盖 ShouldOverriderUrlLoading 方法。
public class HelloWebViewClient : WebViewClient
{
// For API level 24 and later
public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)
{
view.LoadUrl(request.Url.ToString());
return false;
}
}
然后创建自定义 WebChromeClient 以覆盖 OnPermissionRequest 方法以授予请求。
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());
});
}
}
public class MainActivity : AppCompatActivity
{
private WebView webview1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
webview1 = FindViewById<WebView>(Resource.Id.webView1);
webview1.Settings.JavaScriptEnabled = true;
webview1.Settings.AllowFileAccessFromFileURLs = true;
webview1.Settings.AllowUniversalAccessFromFileURLs = true;
webview1.SetWebViewClient(new HelloWebViewClient());
webview1.SetWebChromeClient(new MyWebChromeClient(this));
checkpermission();
}
private void checkpermission()
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) == (int)Permission.Granted)
{
// We have permission, go ahead and use the camera.
webview1.LoadUrl("https://googlechrome.github.io/samples/image-capture/index.html");
}
else
{
// Camera permission is not granted. If necessary display rationale & request.
ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.Camera }, 1);
webview1.LoadUrl("https://googlechrome.github.io/samples/image-capture/index.html");
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}