如何从 Webview 中访问相机?

Posted

技术标签:

【中文标题】如何从 Webview 中访问相机?【英文标题】:How to access the camera from within a Webview? 【发布时间】:2021-11-17 17:41:58 【问题描述】:

在我的 android 应用程序中,我试图在 WebView 上加载一个网页(必须访问相机)。在我的笔记本电脑上,当我加载网页时,我可以访问相机。

显示html 页面上的所有其他内容。

这是我在Manifest.xml 中输入的权限

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.webkit.PermissionRequest" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

我将 SDK 设置如下:

<uses-sdk
    android:minSdkVersion="18"
    android:targetSdkVersion="21" />

这是我的 webview 设置:

private void setMyWebviewSettings(WebSettings MyWebviewSettings) 
    MyWebviewSettings.setAllowFileAccessFromFileURLs(true);
    MyWebviewSettings.setAllowUniversalAccessFromFileURLs(true);
    MyWebviewSettings.setjavascriptCanOpenWindowsAutomatically(true);
    MyWebviewSettings.setJavaScriptEnabled(true);
    MyWebviewSettings.setDomStorageEnabled(true);
    MyWebviewSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    MyWebviewSettings.setBuiltInZoomControls(true);
    MyWebviewSettings.setAllowFileAccess(true);
    MyWebviewSettings.setSupportZoom(true);

如果我可以直接从我的应用程序访问相机(使用正常活动),为什么我不能从WebView 中打开它?!

【问题讨论】:

当您尝试从 webview 打开相机时,您需要设置 webview。请参阅***.com/questions/29290940/… 【参考方案1】:

我也在尝试同样的事情。下面的代码对我有用。

首先在清单文件中,我们必须使用使用权限标签添加相机硬件权限 true。

然后需要接受相机权限才能在您的活动中使用以下行。

webview.setWebChromeClient(new WebChromeClient() 

   @Override
   public void onPermissionRequest(final PermissionRequest request) 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
         request.grant(request.getResources());
      
   

 );

【讨论】:

【参考方案2】:

getUserMedia 通过 WebRTC 这当然是可能的。

设置您的 WebView 以允许权限并使用 loadUrl() 加载您的 HTML:

    WebView myWebView = (WebView) findViewById(R.id.webview);

    myWebView.getSettings().setJavaScriptEnabled(true);
    myWebView.getSettings().setAllowFileAccessFromFileURLs(true);
    myWebView.getSettings().setAllowUniversalAccessFromFileURLs(true);

    myWebView.setWebViewClient(new WebViewClient());
    myWebView.setWebChromeClient(new WebChromeClient() 
        // Grant permissions for cam
        @Override
        public void onPermissionRequest(final PermissionRequest request) 
            Log.d(TAG, "onPermissionRequest");
            MainActivity.this.runOnUiThread(new Runnable() 
                @TargetApi(Build.VERSION_CODES.M)
                @Override
                public void run() 
                    Log.d(TAG, request.getOrigin().toString());
                    if(request.getOrigin().toString().equals("file:///")) 
                        Log.d(TAG, "GRANTED");
                        request.grant(request.getResources());
                     else 
                        Log.d(TAG, "DENIED");
                        request.deny();
                    
                
            );
        


    );

    myWebView.loadUrl(LOCAL_FILE);

然后通过你的JS文件使用getUserMedia,假设你的HTML文件中有&lt;video&gt;标签:

var constraints =  video:  width: 800, height: 800  ;

navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) 
  var video = document.querySelector('video');
  video.srcObject = mediaStream;
  video.onloadedmetadata = function(e) 
    video.play();
  ;
)
.catch(function(err)  console.log(err.name + ": " + err.message); ); // always check for errors at the end.

最后,确保您在清单中设置了权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

【讨论】:

你能帮我解决这个问题吗? ***.com/questions/63695705/…【参考方案3】:

这对我有用。我希望它可以帮助某人。

public class MainActivity extends AppCompatActivity implements 
EasyPermissions.PermissionCallbacks

WebView myWebView;

private String TAG = "TEST";
private PermissionRequest mPermissionRequest;

private static final int REQUEST_CAMERA_PERMISSION = 1;
private static final String[] PERM_CAMERA =
        Manifest.permission.CAMERA;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    myWebView  = new WebView(this);

    myWebView.getSettings().setJavaScriptEnabled(true);
    myWebView.getSettings().setAllowFileAccessFromFileURLs(true);
    myWebView.getSettings().setAllowUniversalAccessFromFileURLs(true);

    //myWebView.setWebViewClient(new WebViewClient());
    myWebView.setWebChromeClient(new WebChromeClient() 
        // Grant permissions for cam
        @Override
        public void onPermissionRequest(final PermissionRequest request) 
            Log.i(TAG, "onPermissionRequest");
            mPermissionRequest = request;
            final String[] requestedResources = request.getResources();
            for (String r : requestedResources) 
                if (r.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) 
                    // In this sample, we only accept video capture request.
                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this)
                                                        .setTitle("Allow Permission to camera")
                                                        .setPositiveButton("Allow", new DialogInterface.OnClickListener() 
                                                            @Override
                                                            public void onClick(DialogInterface dialog, int which) 
                                                                dialog.dismiss();
                                                                mPermissionRequest.grant(new String[]PermissionRequest.RESOURCE_VIDEO_CAPTURE);
                                                                Log.d(TAG,"Granted");
                                                            
                                                        )
                                                        .setNegativeButton("Deny", new DialogInterface.OnClickListener() 
                                                            @Override
                                                            public void onClick(DialogInterface dialog, int which) 
                                                                dialog.dismiss();
                                                                mPermissionRequest.deny();
                                                                Log.d(TAG,"Denied");
                                                            
                                                        );
                    AlertDialog alertDialog = alertDialogBuilder.create();
                    alertDialog.show();

                    break;
                
            
        

        @Override
        public void onPermissionRequestCanceled(PermissionRequest request) 
            super.onPermissionRequestCanceled(request);
            Toast.makeText(MainActivity.this,"Permission Denied",Toast.LENGTH_SHORT).show();
        
    );


    if(hasCameraPermission())
        myWebView.loadUrl("Your URL");
        setContentView(myWebView );
    else
        EasyPermissions.requestPermissions(
                this,
                "This app needs access to your camera so you can take pictures.",
                REQUEST_CAMERA_PERMISSION,
                PERM_CAMERA);
    







private boolean hasCameraPermission() 
    return EasyPermissions.hasPermissions(MainActivity.this, PERM_CAMERA);


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);


@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) 



@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) 



我正在使用 easypermission 库来获取相机权限,记得在 Android Manifest 中为相机添加使用权限

【讨论】:

你能帮我解决这个问题吗? ***.com/questions/63695705/…【参考方案4】:

根据 meuser07 的回答,这对我有用。除了 Manifest.xml 中的权限外,您还需要在运行时检查/授予权限。

希望对你有帮助。

            override fun onPermissionRequest(request: PermissionRequest) 
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
                    if (ContextCompat.checkSelfPermission(this@YourActivity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) 
                                                RxPermissions(this@YourActivity).request(Manifest.permission.CAMERA).subscribe(
                            if (it) request.grant(request.resources)
                        , 
                            Timber.e(it, "Error requesting camera")
                        ).addSubscription()
                     else 
                        request.grant(request.resources)
                    
                
            

我正在使用RxPermission 授予权限。此外,您需要添加此配置。

webView.settings.mediaPlaybackRequiresUserGesture = false

【讨论】:

你能帮我解决这个问题吗? ***.com/questions/63695705/…【参考方案5】:

如果我没记错的话,您只是想打开您的设备相机并在 web 视图中上传新拍摄的照片而不打开其他应用程序,那么您还需要 WRITE_EXTERNAL_STORAGE 权限以及处理文件请求和使用相机创建新文件的方法和将其写入您的设备存储。

我希望这会有所帮助,Open Source (Android Smart WebView) 让我们为您进行设置。

您需要寻找openFileChooser()onShowFileChooser() 方法来了解如何处理来自webview 输入的文件请求并激活您的手机摄像头以在不打开其他应用的情况下捕捉和创建新图像。

【讨论】:

以上是关于如何从 Webview 中访问相机?的主要内容,如果未能解决你的问题,请参考以下文章

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

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

如何修复在flutter webview中无法访问视频流(NotAllowedError)以使用html5 + webRTC相机api?

无法通过 react-native-webview 访问相机

有没有办法让颤动的 webview 使用 android 相机进行文件上传?如何在 webview_flutter 中打开文件选择器?

在 WebView 中从相机或图库上传图像