最近的项目需要和H5结合开发,其中一个功能就是要处理H5的选择文件功能,我也是第一次解决这种问题,首先就去百度看了很多博客写的处理方法,但是都没有很全面的解决方法,因为Android版本的不同,权限也相应的不一样,所以我就整理了针对不同的权限的解决方法。我主要是参考了http://download.csdn.net/detail/djcken/8776691这个博主的解决办法,并在他的基础上进行了修改。
首先是要继承WebChromeClient这个类,WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等。
public class MyWebChomeClient extends WebChromeClient {
private OpenFileChooserCallBack mOpenFileChooserCallBack;
public ReWebChomeClient(OpenFileChooserCallBack openFileChooserCallBack) {
mOpenFileChooserCallBack = openFileChooserCallBack;
}
//针对 Android 5.0+
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback,
android.webkit.WebChromeClient.FileChooserParams fileChooserParams) {
mOpenFileChooserCallBack.openFileChooser5CallBack(webView, valueCallback, fileChooserParams);
return true;
}
//针对 Android版本 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mOpenFileChooserCallBack.openFileChooserCallBack(uploadMsg, acceptType);
}
// 针对 Android版本 < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
//针对 Android版本 > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}
//回调的接口
public interface OpenFileChooserCallBack {
void openFileChooserCallBack(ValueCallback<Uri> uploadMsg, String acceptType);
void openFileChooser5CallBack(WebView webView, ValueCallback<Uri[]> valueCallback,
android.webkit.WebChromeClient.FileChooserParams fileChooserParams);
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
// return super.onJsAlert(view, url, message, result);
return true;
}
}
接下来就是设置,一句代码就可以。
webView.setWebChromeClient(new ReWebChomeClient(this));
private static final int REQUEST_CODE_PICK_IMAGE = 0;
private static final int REQUEST_CODE_IMAGE_CAPTURE = 1;
private Intent mSourceIntent;
//针对5.0以下版本
private ValueCallback<Uri> mUploadMsg;
//这对5.0以上版本
private ValueCallback<Uri[]> mValueCallback;
@Override
public void openFileChooserCallBack(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMsg = uploadMsg;
showOptions();
}
@Override
public void openFileChooser5CallBack(WebView webView, ValueCallback<Uri[]> valueCallback, WebChromeClient.FileChooserParams fileChooserParams) {
mValueCallback = valueCallback;
showOptions();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_CANCELED) {
if (mUploadMsg != null) {
mUploadMsg.onReceiveValue(null);
mUploadMsg = null;
}
if (mValueCallback != null) {
mValueCallback.onReceiveValue(null);
mValueCallback = null;
}
}
switch (requestCode) {
case REQUEST_CODE_IMAGE_CAPTURE:
case REQUEST_CODE_PICK_IMAGE: {
try {
if (mUploadMsg != null) {
String sourcePath = ImageUtil.retrievePath(this, mSourceIntent, data);
if (TextUtils.isEmpty(sourcePath) || !new File(sourcePath).exists()) {
Log.w(TAG, "sourcePath empty or not exists.");
break;
}
File file = new File(PictureUtil.bitmapToPath(sourcePath));
Uri uri = Uri.fromFile(file);
mUploadMsg.onReceiveValue(uri);
mUploadMsg = null;
} else if (mValueCallback != null) {
Uri[] uris = new Uri[1];
String sourcePath = ImageUtil.retrievePath(this, mSourceIntent, data);
if (TextUtils.isEmpty(sourcePath) || !new File(sourcePath).exists()) {
Log.w(TAG, "sourcePath empty or not exists.");
break;
}
File file = new File(PictureUtil.bitmapToPath(sourcePath));
uris[0] = Uri.fromFile(file);
if (uris[0] != null) {
mValueCallback.onReceiveValue(uris);
}
mValueCallback = null;
}
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
}
public void showOptions() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setOnCancelListener(new ReOnCancelListener());
alertDialog.setTitle(R.string.options);
alertDialog.setItems(R.array.options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
mSourceIntent = ImageUtil.choosePicture();
startActivityForResult(mSourceIntent, REQUEST_CODE_PICK_IMAGE);
} else {
mSourceIntent = ImageUtil.takeBigPicture();
startActivityForResult(mSourceIntent, REQUEST_CODE_IMAGE_CAPTURE);
}
}
}
);
alertDialog.show();
}
//这个必须要写,要不然第一次取消选择文件后第二次就调用不了选择文件这个功能了,所以一定要写
private class ReOnCancelListener implements DialogInterface.OnCancelListener {
@Override
public void onCancel(DialogInterface dialogInterface) {
if (mUploadMsg != null) {
mUploadMsg.onReceiveValue(null);
mUploadMsg = null;
}
if (mValueCallback != null) {
mValueCallback.onReceiveValue(null);
mValueCallback = null;
}
}
}