Android:WebView 中的网络摄像头错误(摄像头权限不起作用)

Posted

技术标签:

【中文标题】Android:WebView 中的网络摄像头错误(摄像头权限不起作用)【英文标题】:Android : Webcam Error in WebView (Camera Permission not working) 【发布时间】:2020-08-13 04:04:43 【问题描述】:

我已经创建了 WebView Activity 并加载了 https://web.doar.zone/coronavirus

这个 URL 需要相机权限,我在 android 中获得了运行时权限。

这里是MainActivity.java的完整代码:

public class MainActivity extends AppCompatActivity 

    private static final String TAG = "MainActivity";

    Context context;

    ActivityMainBinding binding;

    private String url = "https://web.doar.zone/coronavirus";

    @Override
    protected void onResume() 
        super.onResume();
        checkCameraPermission();
    

    private void checkCameraPermission() 
        int writeExternalStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
        if (writeExternalStorage != PackageManager.PERMISSION_GRANTED) 
            ActivityCompat.requestPermissions(this, new String[]Manifest.permission.CAMERA, 1001);
        
    

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1001) 
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) 
                //Do your stuff
                openWebView();
             else 
                checkCameraPermission();
            
        
    

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        context = getApplicationContext();

        openWebView();
    

    @SuppressLint("SetjavascriptEnabled")
    void openWebView() 

        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        final NetworkInfo networkInfo;
        if (connectivityManager != null) 
            networkInfo = connectivityManager.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isConnectedOrConnecting()) 
                binding.internetTextView.setVisibility(View.INVISIBLE);
                binding.webView.setVisibility(View.VISIBLE);
                //binding.webView.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/41.0.2228.0 Safari/537.3");
                binding.webView.getSettings().setJavaScriptEnabled(true);
                binding.webView.getSettings().setUseWideViewPort(true);
                binding.webView.getSettings().setDomStorageEnabled(true);
                binding.webView.setInitialScale(1);
                binding.webView.setWebChromeClient(new MyWebChromeClient());
                binding.webView.setWebViewClient(new WebViewClient() 

                    @Override
                    public boolean shouldOverrideUrlLoading(WebView webview, String url) 
                        Uri uri = Uri.parse(url);
                        if (uri.getScheme().contains("whatsapp") || uri.getScheme().contains("tel")) 
                            try 
                                Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
                                if (intent.resolveActivity(getPackageManager()) != null)
                                    startActivity(intent);
                                return true;
                             catch (URISyntaxException use) 
                                Log.e("TAG", use.getMessage());
                            
                         else 
                            webview.loadUrl(url);
                        

                        return true;
                    

                    @Override
                    public void onPageFinished(WebView view, String url) 
                        super.onPageFinished(view, url);
                    
                );
                binding.webView.loadUrl(url);
             else 

                binding.internetTextView.setVisibility(View.VISIBLE);
                binding.buttonTryAgain.setVisibility(View.VISIBLE);
                binding.webView.setVisibility(View.INVISIBLE);

                Toast.makeText(context, "Connect to Internet and Refresh Again", Toast.LENGTH_LONG).show();
            
         else 
            binding.internetTextView.setVisibility(View.VISIBLE);
            binding.buttonTryAgain.setVisibility(View.VISIBLE);
            binding.webView.setVisibility(View.INVISIBLE);

            Toast.makeText(context, "Connect to Internet and Refresh Again", Toast.LENGTH_LONG).show();
        
    


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) 
        if (event.getAction() == KeyEvent.ACTION_DOWN) 
            if (keyCode == KeyEvent.KEYCODE_BACK) 
                if (binding.webView.canGoBack()) 
                    binding.webView.goBack();
                 else 
                    finish();
                
                return true;
            

        
        return super.onKeyDown(keyCode, event);
    

    class MyWebChromeClient extends WebChromeClient 

        MyWebChromeClient() 
            // TODO Auto-generated constructor stub
            binding.pb.setProgress(0);
        

        @Override
        public void onPermissionRequest(final PermissionRequest request) 
            super.onPermissionRequest(request);
            //request.grant(request.getResources());
        

        public void onProgressChanged(WebView view, int progress) 
            if (progress < 100  /* && pBar.getVisibility() == View.VISIBLE*/) 
                binding.pb.setVisibility(View.VISIBLE);
            
            binding.pb.setProgress(progress);
            if (progress == 100) 
                binding.pb.setVisibility(View.GONE);
            
        
    

现在我收到如下错误当我评论这一行时:

request.grant(request.getResources());

如果我取消注释这一行,那么我会得到:

 java.lang.IllegalStateException: Either grant() or deny() has been already called.
    at org.chromium.android_webview.permission.AwPermissionRequest.c(PG:3)
    at org.chromium.android_webview.permission.AwPermissionRequest.b(PG:1)
    at Cn.grant(PG:8)
    at com.example.webviewapp.MainActivity$MyWebChromeClient.onPermissionRequest(MainActivity.java:164)
    at org.chromium.android_webview.AwContents.onPermissionRequest(PG:8)
    at android.os.MessageQueue.nativePollOnce(Native Method)
    at android.os.MessageQueue.next(MessageQueue.java:326)
    at android.os.Looper.loop(Looper.java:181)
    at android.app.ActivityThread.main(ActivityThread.java:7078)
2020-04-29 11:52:21.813 4943-4943/com.example.webviewapp W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)

有什么帮助吗?

【问题讨论】:

【参考方案1】:

您已经处理了 android 操作系统的运行时相机权限。我们还需要在 webview 中授予摄像头权限 (RESOURCE_VIDEO_CAPTURE)。

首先调用下面的方法打开相机,无需用户手势:

binding.webView.getSettings().setMediaPlaybackRequiresUserGesture(false);

像这样调用request.grant(request.getResources()) 方法将授予所有请求的权限。 为避免这种情况,您应该只授予您需要的权限,即RESOURCE_VIDEO_CAPTURE

@Override
public void onPermissionRequest(final PermissionRequest request) 
    final String[] requestedResources = request.getResources();
    for (String r : requestedResources) 
        if (r.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) 
            request.grant(new String[]PermissionRequest.RESOURCE_VIDEO_CAPTURE);
            break;
        
    

在您的代码中,这一行导致了问题:super.onPermissionRequest(request); 这个超级方法调用拒绝了权限。

【讨论】:

感谢您的回答。相机打开成功,但在左上角显示一半宽度和高度 @PratikButani 我不知道怎么回事,因为这条线binding.webView.setInitialScale(1); 谢谢,我删除了binding.webView.setInitialScale(1); 现在可以使用了。 @AnkitMakwana 保留此内容后,我面临一个问题。当我在浏览器中打开外部链接(shouldOverrideUrlLoading 的帮助)时。然后回到 webview 网络摄像头正在禁用。但是当我单击主页按钮并再次进入应用程序时工作。是什么原因,你遇到过这个问题吗? @AnkitMakwana 问题是当我通过 webview 访问外部链接时 cam 被禁用,因为焦点发生了变化,所以我在获得 focus.issue 时启用了 cam。【参考方案2】:

首先检查您的相机权限,然后加载您的网络视图。你怎么能这样做:

1.在您的onCreate 方法中删除openWebView()

2.用新方法替换checkCameraPermission()

 private void checkCameraPermissionAndStartWebView() 
      int writeExternalStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
      if (writeExternalStorage != PackageManager.PERMISSION_GRANTED) 
         ActivityCompat.requestPermissions(this, new String[]Manifest.permission.CAMERA, 1001);
       else 
         openWebView();
      
 

3.in onResumeonRequestPermissionsResult 调用新的 checkCameraPermissionAndStartWebView 方法

【讨论】:

以上是关于Android:WebView 中的网络摄像头错误(摄像头权限不起作用)的主要内容,如果未能解决你的问题,请参考以下文章

如何在android的webview中启用前置摄像头

Android:WebView-未为会议启用摄像头和麦克风

如何在 Android WebView 中允许访问相机

如何从 webview 中的按钮启动相机 -Android

Android:WebView - 没有为会议启用摄像头和麦克风

添加自定义android webview错误页面