一、概述
这几天由于项目的需要,需要我们app端实现H5的图片上传功能,经过一系列的研究知道了webview中的一个方法,通过实现这个方法就能实现webview上传图片的功能。
二、思路
首先我们需要实现openFileChooser这个方法通过,这个方法相当于一个接口,如果你实现了这个接口的相当于给了webview读取本地文件的权利,不过这个方法在android3.0、4.1、5.0都有过更新,所以我们要去实现多个openFileChooser方法。在实现了openFileChooser这个方法之后JS只是读取到了我们这边的文件数据,但是上传功能我们还是要自己去做,我们在openFileChooser中去上传文件,上传之后我们需要通过onActivityResult方法获取这个图片的Url,然后在去调用上传的方法去上传这个文件。好了思路就是这样,下面我们看一下代码。首先我们去实现openFileChooser方法:
private class MyWebChromeClient extends WebChromeClient { // For Android < 3.0 public void openFileChooser(ValueCallback<Uri> valueCallback) { mUploadMessage = valueCallback; goToPhotos(); } // For Android >= 3.0 public void openFileChooser(ValueCallback valueCallback, String acceptType) { mUploadMessage = valueCallback; goToPhotos(); } //For Android >= 4.1 public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) { mUploadMessage = valueCallback; goToPhotos(); } //5.0 @Override public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { if (mUploadMessage != null) { mUploadMessage.onReceiveValue(null); } mValueCallback = filePathCallback; goToPhotos(); return true; }
}
goToPhotos方法其实就是一个跳转相册的方法:
/**
* 进入本地图库
*/
private void goToPhotos() {
Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"
String IMAGE_UNSPECIFIED = "image/*"; // ①
innerIntent.setType(IMAGE_UNSPECIFIED); // 查看类型
Intent wrapperIntent = Intent.createChooser(innerIntent, null);
startActivityForResult(wrapperIntent, FILECHOOSER_RESULTCODE);
}
这个注释①我说一下,这个地方是设置查看文件的类型,image是代表的是图片的意思,后面的*代表格式,也就是代表全部格式的图片,其实还可以设置image/.png 等类型的图片
最后一步,看一下我们回调然后上传图片:
/**
* 返回文件选择
*/
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == FILECHOOSER_RESULTCODE) {
uploadImgFromSysPhotos(resultCode, intent);
}
}
/**
*
*
* @param resultCode
* @param intent
* @author andYa
*/
private void uploadImgFromSysPhotos(int resultCode, Intent intent) {
if (mUploadMessage != null) {//5.0以下
Uri result = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
} else if (mValueCallback != null) {//5.0+
Uri[] uris = new Uri[1];
uris[0] = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mValueCallback.onReceiveValue(uris);
}
}
}
好了基本的功能就可以实现了不过如果你自己写过之后你会发现有几个问题,第一个问题,如果我们进入相册然后没选图片就返回了,那么我们第二次点击上传图片的地方的时候是不能进入相册的。第二个问题就是有些5.0以下的手机是上传不了文件的。第三个问题也就是如果在release环境上面我们是上传不了文件的。
三、坑的解决
问题一:
其实之所以出现问题一的原因就是当你进入相册之后退出来,JS一直在等待着你选择图片Url的回调,你没选肯定是没有回调的