Choose camera in file upload in cordova application on android without using cordova camera

前端 未结 6 2078
野趣味
野趣味 2021-01-07 17:01

So i made a cordova app, i added android platform and made a simple html with an imput field



        
6条回答
  •  盖世英雄少女心
    2021-01-07 17:34

    Inspired from Gilberto answer, here is my adaptation:

    1. Always open the camera
    2. Ask for permissions before opening the actual camera, when permission is granted, open camera, otherwise, display a Toast.
    3. If permissions are denied, clicking on the input fill ask for it, no need to refresh or change screen etc.

    There is 4 new methods: one for receiving the permission, one to check the permission, one for create the image file before taking the picture and one to open the camera.

    Here are those methods

    
        /**
         * Called by the system when the user grants permissions
         *
         * @param requestCode
         * @param permissions
         * @param grantResults
         */
        public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults)
                throws JSONException {
    
            for (int r : grantResults) {
                if (r == PackageManager.PERMISSION_DENIED) {
                    Toast.makeText(cordova.getActivity(), "Autorisation pour ouvrir la caméra refusé", Toast.LENGTH_LONG)
                            .show();
                    mUploadCallbackLollipop.onReceiveValue(null);
                    mUploadCallbackLollipop = null;
                    return;
                }
            }
    
            if (requestCode == PERM_REQUEST_CAMERA_FOR_FILE) {
                startCameraActivityForAndroidFivePlus();
            }
        }
    
        private File createImageFile() throws IOException {
            @SuppressLint("SimpleDateFormat")
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            String imageFileName = "img_" + timeStamp + "_";
            File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            return File.createTempFile(imageFileName, ".jpg", storageDir);
        }
    
        private void startCameraActivityForAndroidFivePlus() {
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            File photoFile = null;
            try {
                photoFile = createImageFile();
                takePictureIntent.putExtra("PhotoPath", mCapturedPhoto);
            } catch (IOException ex) {
                LOG.e(LOG_TAG, "Image file creation failed", ex);
            }
            if (photoFile != null) {
                mCapturedPhoto = "file:" + photoFile.getAbsolutePath();
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
            } else {
                takePictureIntent = null;
            }
    
            // Fix FileUriExposedException exposed beyond app through ClipData.Item.getUri()
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy(builder.build());
    
            // Run cordova startActivityForResult
            cordova.startActivityForResult(InAppBrowser.this, takePictureIntent, FILECHOOSER_REQUESTCODE_LOLLIPOP);
        }
    
        private boolean checkPermissionForCamera() {
            if (Build.VERSION.SDK_INT >= 23) {
                List permToAsk = new ArrayList();
                if (cordova.getActivity().checkSelfPermission(
                        Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    permToAsk.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
                }
                if (cordova.getActivity()
                        .checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    permToAsk.add(Manifest.permission.CAMERA);
                }
                if (permToAsk.size() > 0) {
                    cordova.requestPermissions(InAppBrowser.this, PERM_REQUEST_CAMERA_FOR_FILE,
                            permToAsk.toArray(new String[permToAsk.size()]));
                    return true;
                }
            }
            return false;
        }
    

    The InAppChromeClient implementation has been updated to just this:

    inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView) {
                        // For Android 5.0+
                        public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback,
                                WebChromeClient.FileChooserParams fileChooserParams) {
    
                            LOG.d(LOG_TAG, "File Chooser 5.0+");
                            // If callback exists, finish it.
                            if (mUploadCallbackLollipop != null) {
                                mUploadCallbackLollipop.onReceiveValue(null);
                            }
                            mUploadCallbackLollipop = filePathCallback;
    
                            // #Update to always open camera app
                            if (checkPermissionForCamera()) {
                                return true;
                            }
    
                            startCameraActivityForAndroidFivePlus();
                            return true;
                        }
                    });
    

    And here are those constants:

        private String mCapturedPhoto;
        private final static int PERM_REQUEST_CAMERA_FOR_FILE = 3;
    

    The complete InAppBrowser.java can be found here.

提交回复
热议问题