如何从Webview中访问摄像头?

时间:2016-11-17 15:45:48

标签: android webview android-permissions

在我的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" />

这是我的网页视图设置:

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内打开它?!

4 个答案:

答案 0 :(得分:5)

通过WebRTC getUserMedia肯定可以做到这一点。

设置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文件中有<video>标记:

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" />

答案 1 :(得分:2)

如果我没错,您只需打开设备相机并在webview中上传新捕获的照片而无需打开其他应用程序,那么您还需要WRITE_EXTERNAL_STORAGE权限以及处理文件请求和创建新文件的方法相机并将其写入您的设备存储。

我希望这会有所帮助, Open Source (Android Smart WebView) 可以为您设置一些内容。

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

答案 2 :(得分:1)

这对我有用。我希望它有所帮助。

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中为相机添加使用权限

答案 3 :(得分:1)

根据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