WebView上传图片实现(本文只实现图库选择)
1.webview的缺陷
相信刚接触过webview的童鞋,一定以为webview使用很简单,就是把uri传给webview即可,然后天真的以为webview就可以像浏览器那样,可以实现网页内的全部功能。But 突然有一天,新增业务需求:在webview内上传图片至服务器,然后你去测试,就傻眼了,点击没反应。
2.webview不能上传的原因
自行google
3.webview不能上传的解决方案(这才是重点)
3.1 解决方案(不包括android 4.4.2)
一般情况下我们的webview都是这样初始化的:
public void initWebview() throws Exception {
isWebViewNull();
WebSettings webSettings = webView.getSettings();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webSettings.setBlockNetworkImage(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webSettings.setLoadsImagesAutomatically(true);
} else {
webSettings.setLoadsImagesAutomatically(false);
}
webSettings.setDomStorageEnabled(true);
webSettings.setJavaScriptEnabled(true);
//TODO
webSettings.setUseWideViewPort(true);
webSettings.setAllowFileAccess(true);
webSettings.setUserAgentString(webSettings.getUserAgentString());
webSettings.setPluginState(WebSettings.PluginState.ON);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
}
重点是对webchromeClient的重写,适用于大部分的手机
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mUploadCallbackAboveL;
private final int RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP = 1;
private final int RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP = 2;
/**
*内部类
*/
class MyWebChromeClient extends WebChromeClient {
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
if (mUploadMessage != null)
return;
mUploadMessage = uploadMsg;
selectImage(RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP);
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
// For Android > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}
// For Android 5.0+
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
mUploadCallbackAboveL = filePathCallback;
selectImage(RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP);
return true;
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
progressBar.setSecondaryProgress(newProgress);
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
tv_title.setText(TextUtils.isEmpty(webTitle) ? title : webTitle);
}
}
String compressPath = "";
/**打开图库,同时处理图片(项目业务需要统一命名)*/
private void selectImage(int resultCode) {
LogUtil.e("resultCode="+resultCode);
compressPath = Environment.getExternalStorageDirectory().getPath() + "/QWB/temp";
File file = new File(compressPath);
if (!file.exists()) {
file.mkdirs();
}
compressPath = compressPath + File.separator + "compress.png";
File image = new File(compressPath);
if (image.exists()) {
image.delete();
}
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
Intent wrapperIntent = Intent.createChooser(intent, "File Chooser");
startActivityForResult(wrapperIntent, resultCode);
}
/**选择后,回传值*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (mUploadMessage == null && mUploadCallbackAboveL == null) {
return;
}
Uri uri = null;
switch (requestCode) {
case RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP: {
uri = afterChosePic(data);
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(uri);
mUploadMessage = null;
}
}
break;
case RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP: {
uri = afterChosePic(data);
if (mUploadCallbackAboveL != null) {
mUploadCallbackAboveL.onReceiveValue(new Uri[]{uri});
mUploadCallbackAboveL = null;
}
}
break;
}
}
/**
* 选择照片后结束
*
* @param data
*/
private Uri afterChosePic(Intent data) {
if (data == null) {
return null;
}
String path = BitmapUtils.getPath(this, data.getData());
String[] names = path.split("\\.");
String endName = null;
if (names != null) {
endName = names[names.length - 1];
}
if (endName != null) {
compressPath = compressPath.split("\\.")[0] + "." + endName;
}
LogUtil.e("path===" + path + ",compress=" + compressPath + ",endName=" + endName);
File newFile = FileUtils.compressFile(path, compressPath);
return Uri.fromFile(newFile);
}
3.2解决方案(针对android 4.4.2,我的测试手机是samsung galaxy note2 android 4.4.2)
此方案不是我原创,是我在stackoverflow上面发现的,经测试,相当给力
但是这个demo,局限性很大,不能动态的修改url,此为一大遗憾
代码较多,并牵扯到我并不熟悉的framework层,以及ndk的编码,现仅奉上demo作为分享,
Demo下载地址