Android WebView supports input file enables camera and photo selection function
- 2021-11-13 02:38:11
- OfStack
If webview wants to adjust input-file photo or file selection function, it can rewrite the specified method in webview. setWebChromeClient method to intercept input event of webview and do our corresponding operation.
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 the web page
} else {
progressBar.setProgress(newProgress);// Setting progress values
progressBar.setVisibility(View.VISIBLE);// Show the progress bar when you start loading the web page
}
}
/**
* 8(Android 2.2) <= API <= 10(Android 2.3) Callback this method
*/
private void openFileChooser(android.webkit.ValueCallback<Uri> uploadMsg) {
Log.e("WangJ", " Operation method openFileChooser-1");
// (2) When this method calls back, it explains the version API < 21 At this point, assign the result to the mUploadCallbackBelow , 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<Uri> uploadMsg, String acceptType) {
Log.e("WangJ", " Operation method openFileChooser-2 (acceptType: " + acceptType + ")");
// We don't distinguish here input Parameters, take pictures directly
openFileChooser(uploadMsg);
}
/**
* 16(Android 4.1.2) <= API <= 20(Android 4.4W.2) Callback this method
*/
public void openFileChooser(android.webkit.ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
Log.e("WangJ", " Operation method openFileChooser-3 (acceptType: " + acceptType + "; capture: " + capture + ")");
// We don't distinguish here input Parameters, take pictures directly
openFileChooser(uploadMsg);
}
/**
* API >= 21(Android 5.0.1) Callback this method
*/
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, FileChooserParams fileChooserParams) {
Log.e("WangJ", " Operation method onShowFileChooser");
// (1) When this method calls back, it explains the version API >= 21 At this point, assign the result to the mUploadCallbackAboveL , make it != null
mUploadCallbackAboveL = valueCallback;
takePhoto();
return true;
}
});
The java code here is to intercept input events, which makes a lot of judgments about api versions. Different versions of api call different methods, and the following are 1 other methods:
Method of adjusting camera/selecting file: takePhoto ();
/**
* Call camera
*/
private void takePhoto() {
// Turn up the camera by specifying the storage location for taking pictures
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 pictures (excluding camera photos) , You do not need to post a broadcast that refreshes the gallery 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) {
// Pass up (1) , (2) Two assignment operations, where you can decide which processing method to use according to whether their values are empty or not
if (mUploadCallbackBelow != null) {
chooseBelow(resultCode, data);
} else if (mUploadCallbackAboveL != null) {
chooseAbove(resultCode, data);
} else {
Toast.makeText(this, " An error occurred ", Toast.LENGTH_SHORT).show();
}
}
}
One other method:
/**
* Android API < 21(Android 5.0) Version callback processing
* @param resultCode Select the return code of the file or photo
* @param data Select the return result of a file or photo
*/
private void chooseBelow(int resultCode, Intent data) {
Log.e("WangJ", " Returns the calling 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 {
// Set up the camera in the way of specifying the image storage path, and return after success data Empty
Log.e("WangJ", " Customize results: " + imageUri.toString());
mUploadCallbackBelow.onReceiveValue(imageUri);
}
} else {
mUploadCallbackBelow.onReceiveValue(null);
}
mUploadCallbackBelow = null;
}
/**
* Android API >= 21(Android 5.0) Version callback processing
* @param resultCode Select the return code of the file or photo
* @param data Select the return result of a file or photo
*/
private void chooseAbove(int resultCode, Intent data) {
Log.e("WangJ", " Returns the calling method --chooseAbove");
if (RESULT_OK == resultCode) {
updatePhotos();
if (data != null) {
// This is the processing of 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", " Customize results: " + imageUri.toString());
mUploadCallbackAboveL.onReceiveValue(new Uri[]{imageUri});
}
} else {
mUploadCallbackAboveL.onReceiveValue(null);
}
mUploadCallbackAboveL = null;
}
private void updatePhotos() {
// It doesn't matter if the broadcast is multiple (that is, it will be sent when the photo selection is successful), just wake up the system and refresh the media file
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(imageUri);
sendBroadcast(intent);
}
Related global variables:
private android.webkit.ValueCallback<Uri[]> mUploadCallbackAboveL;
private android.webkit.ValueCallback<Uri> mUploadCallbackBelow;
private Uri imageUri;
private int REQUEST_CODE = 1234;
Summarize