Android WebView supports input file to enable camera / select photos

Time:2019-11-7

To activate the input file photographing or file selection function of WebView, you can override the specified method in the webview.setwebchromeclient method to intercept the input event of WebView and do our corresponding operations.

Android code

webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (newProgress == 100) {
                    ProgressBar. Setvisibility (view. Gone); // the progress bar disappears after loading
                } else {
                    ProgressBar. Setprogress (newprogress); // set the progress value
                    ProgressBar. Setvisibility (view. Visible); // display the progress bar when starting to load the web page
                }
            }
 
            /**
             *8 (Android 2.2) < = API < = 10 (Android 2.3) callback this method
             */
            private void openFileChooser(android.webkit.ValueCallback uploadMsg) {
                Log. E ("wangj", "operation method openfilechooser-1");
                //(2) when the method is called back, it indicates that the version API is < 21. In this case, assign the result to muploadcallbackbelow to make it! = null
                mUploadCallbackBelow = uploadMsg;
                takePhoto();
            }
 
            /**
             *11 (Android 3.0) < = API < = 15 (Android 4.0.3) callback this method
             */
            public void openFileChooser(android.webkit.ValueCallback uploadMsg, String acceptType) {
                Log. E ("wangj", "operation method openfilechooser-2 (accepttype:" + accepttype + ")");
                //Here we don't distinguish the input parameters, just take photos
                openFileChooser(uploadMsg);
            }
 
            /**
             *16 (Android 4.1.2) < = API < = 20 (Android 4.4w. 2) callback this method
             */
            public void openFileChooser(android.webkit.ValueCallback uploadMsg, String acceptType, String capture) {
                Log. E ("wangj", "operation method openfilechooser-3 (accepttype:" + accepttype + "; capture:" + capture + ")");
                //Here we don't distinguish the input parameters, just take photos
                openFileChooser(uploadMsg);
            }
 
            /**
             *API > = 21 (Android 5.0.1) callback this method
             */
            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback valueCallback, FileChooserParams fileChooserParams) {
                Log. E ("wangj", "operation method onshowfilechooser");
                //(1) when the method is called back, it indicates that the version API > = 21. In this case, assign the result to muploadcallbackabovel to make it! = null
                mUploadCallbackAboveL = valueCallback;
                takePhoto();
                return true;
            }
        });

The Java code here is to intercept the input event. It makes a lot of judgments about the API version. Different versions of the API call different methods. Here are some other methods:

The method of setting up camera / selecting file: takephoto();

/**
     *Call camera
     */
    private void takePhoto() {
        //Set up the camera by specifying the location of the photo storage
        String filePath = Environment.getExternalStorageDirectory() + File.separator
                + Environment.DIRECTORY_PICTURES + File.separator;
        String fileName = "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
        imageUri = Uri.fromFile(new File(filePath + fileName));
 
//        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
//        startActivityForResult(intent, REQUEST_CODE);
 
        //Select the picture (excluding camera taking), and the broadcast of refreshing the gallery will not be sent after success
//        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
//        i.addCategory(Intent.CATEGORY_OPENABLE);
//        i.setType("image/*");
//        startActivityForResult(Intent.createChooser(i, "Image Chooser"), REQUEST_CODE);
 
        Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
 
        Intent Photo = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
 
        Intent chooserIntent = Intent.createChooser(Photo, "Image Chooser");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});
 
        startActivityForResult(chooserIntent, REQUEST_CODE);
    }

Onactivityresult callback:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            //After the above two assignment operations (1) and (2), we can decide which processing method to use according to whether its value is empty
            if (mUploadCallbackBelow != null) {
                chooseBelow(resultCode, data);
            } else if (mUploadCallbackAboveL != null) {
                chooseAbove(resultCode, data);
            } else {
                Toast. Maketext (this, "error occurred", toast. Length_short). Show();
            }
        }
    }

Other methods:

/**
     *Callback processing for Android API < 21 (Android 5.0)
     *@ param resultcode select the return code of the file or photo
     *@ param data select the return result of file or photo
     */
    private void chooseBelow(int resultCode, Intent data) {
        Log. E ("wangj", "return call method -- choosebelow");
 
        if (RESULT_OK == resultCode) {
            updatePhotos();
 
            if (data != null) {
                //This is for file path processing
                Uri uri = data.getData();
                if (uri != null) {
                    Log. E ("wangj", "system return URI:" + URI. Tostring());
                    mUploadCallbackBelow.onReceiveValue(uri);
                } else {
                    mUploadCallbackBelow.onReceiveValue(null);
                }
            } else {
                //Start the camera by specifying the image storage path, and the data returned after success is empty
                Log. E ("wangj", "custom result:" + imageuri. Tostring());
                mUploadCallbackBelow.onReceiveValue(imageUri);
            }
        } else {
            mUploadCallbackBelow.onReceiveValue(null);
        }
        mUploadCallbackBelow = null;
    }
 
    /**
     *Callback processing for Android API > = 21 (Android 5.0)
     *@ param resultcode select the return code of the file or photo
     *@ param data select the return result of file or photo
     */
    private void chooseAbove(int resultCode, Intent data) {
        Log. E ("wangj", "return call method -- chooseabove");
 
        if (RESULT_OK == resultCode) {
            updatePhotos();
 
            if (data != null) {
                //Here is the processing for selecting pictures from files
                Uri[] results;
                Uri uriData = data.getData();
                if (uriData != null) {
                    results = new Uri[]{uriData};
                    for (Uri uri : results) {
                        Log. E ("wangj", "system return URI:" + URI. Tostring());
                    }
                    mUploadCallbackAboveL.onReceiveValue(results);
                } else {
                    mUploadCallbackAboveL.onReceiveValue(null);
                }
            } else {
                Log. E ("wangj", "custom result:" + imageuri. Tostring());
                mUploadCallbackAboveL.onReceiveValue(new Uri[]{imageUri});
            }
        } else {
            mUploadCallbackAboveL.onReceiveValue(null);
        }
        mUploadCallbackAboveL = null;
    }
 
    private void updatePhotos() {
        //It doesn't matter if the broadcast is sent multiple times (i.e. when the photos are selected successfully), but it just wakes up the system to refresh the media files
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(imageUri);
        sendBroadcast(intent);
    }

Related global variables:

private android.webkit.ValueCallback mUploadCallbackAboveL;
private android.webkit.ValueCallback mUploadCallbackBelow;
private Uri imageUri;
private int REQUEST_CODE = 1234;

Original reference link: https://blog.csdn.net/qq_35373333/article/details/79565629

Recommended Today

Binary tree explanation and C + + implementation of common operations

Binary tree bedding tree The linear table, stack, queue, string and so on that we mainly introduced in the previous articles are all one-to-onelinear structureThe tree we are talking about today is a typical oneNonlinear structureThe characteristic of non-linear structure is that the direct precursor of any node, if it exists, must be unique. If […]