WebView上傳圖片解決方案(包括4.4.2以及其它)
阿新 • • 發佈:2019-01-22
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下載地址