1首先 配置动态权限:理解onShowFileChooser或openFileChooser
//变量
private ValueCallback<Uri> uploadMessage;
private ValueCallback<Uri[]> uploadMessageAboveL;
webView.setWebChromeClient(new WebChromeClient() {
//For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
uploadMessageAboveL = filePathCallback;
uploadPicture();
return true;
}
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
uploadMessage = valueCallback;
uploadPicture();
}
});
注意:
onShowFileChooser该方法的作用,告诉当前APP,打开一个文件选择器,比如:打开相册、启动拍照或打开本地文件管理器,实际上更好的理解,WebView加载包含上传文件的表单按钮,HTML定义了input标签,同时input的type类型为file,手指点击该按钮,回调onShowFileChooser这个方法,在这个重写的方法里面打开相册、启动照片或打开本地文件管理器,甚至做其他任何的逻辑处理,点击一次回调一次的前提是请求被取消,而取消该请求回调的方法:给ValueCallback接口的onReceiveValue抽象方法传入null,同时onShowFileChooser方法返回true;
在所有发布的SDK版本中,openFileChooser是一个隐藏的方法,使用onShowFileChooser代替,但是最好同时重写showFileChooser和openFileChooser方法,Android 4.4.X以上的系统回调onShowFileChooser方法,低于或等于Android 4.4.X的系统回调openFileChooser方法,只重写onShowFileChooser或openFileChooser造成在有的系统可以正常回调,在有的系统点击没有反应。
这里有一个问题是,1当没有权限时,跳到设置里设置权限返回后,2或者点击“取消”或返回按钮,无法重复回调onShowFileChooser或openFileChooser方法(ps即无法再次点击➕弹出对话框)
解决方法:
/**
*取消mFilePathCallback回调
*/
private void cancelFilePathCallback() {
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null);
uploadMessage = null;
} else if (uploadMessageAboveL != null) {
uploadMessageAboveL.onReceiveValue(null);
uploadMessageAboveL = null;
}
}
在不期待回调mFilePathCallback的onReceiveValue方法时,调cancelFilePathCallback(),解决点击上传按钮无法重复回调的问题。(权限失败时、取消时、跳到设置时调用)
当然上传的图片最好压缩一下。
拍照例子的代码:(分为7.0时候fileprovider和普通uri)
/**
* 拍照
*/
private void takePhoto() {
StringBuilder fileName = new StringBuilder();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileName.append(UUID.randomUUID()).append("_upload.png");
File tempFile = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName.toString());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri uri = FileProvider.getUriForFile(mContext, com.youtoo.publics.BuildConfig.APPLICATION_ID + ".fileProvider", tempFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
} else {
Uri uri = Uri.fromFile(tempFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
mCurrentPhotoPath = tempFile.getAbsolutePath();
startActivityForResult(intent, REQUEST_CODE_CAMERA);
}
在onActivityResult回调里 也要进行判断是否取消时调用mFilePathCallback回调
if (requestCode==RESULT_CANCELED) {
//一定要返回null,否则<input file> 就是没有反应
cancelFilePathCallback();
}
至此这些问题解决。