针对Webview 支持上传本地图片情况,查询大量资料后发现对版本4.4兼容没有现成的解决方案,目前根据现有开源源码做个修改,可以支持兼容支持4.4版本上传图片:
具体是在onActivityResult 里多加了层判断:
/*
* 若当前版本API为19, 则把Uri路径转换成new File性质的Uri路径
* 若非 则按照之前方法调用即可
* */
if (Build.VERSION.SDK_INT == 19) {
String realPathFromURI = getRealPathFromURI(intent.getData());
File file = new File(realPathFromURI);
if(file.exists()){
Uri uri = Uri.fromFile(file);
mFileUploadCallbackFirst.onReceiveValue(uri);
}
} else {
mFileUploadCallbackFirst.onReceiveValue(intent.getData());
}
根据Uri 获取图片真实路径的方法用的是:
/*
*
* 获取Uri图片真实路径的方法
* */
public String getRealPathFromURI(Uri contentUri) {
String res = null;
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = mContext.getContentResolver().query(contentUri, proj, null, null, null);
if (cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
此方法,测试后webview可以兼容4.4版本上传本地图片。
修改源码后的所有代码 如下:
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.DownloadManager;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Environment;
import android.os.Message;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Base64;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ClientCertRequest;
import android.webkit.ConsoleMessage;
import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.PermissionRequest;
import android.webkit.SslErrorHandler;
import android.webkit.URLUtil;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
/*
* Android-AdvancedWebView (https://github.com/delight-im/Android-AdvancedWebView)
* Copyright (c) delight.im (https://www.delight.im/)
* Licensed under the MIT License (https://opensource.org/licenses/MIT)
*/
/**
* Advanced WebView component for Android that works as intended out of the box
*/
@SuppressWarnings("deprecation")
public class MyWebView extends WebView {
private Context mContext;
public interface Listener {
void onPageStarted(String url, Bitmap favicon);
void onPageFinished(String url);
void onPageError(int errorCode, String description, String failingUrl);
void onDownloadRequested(String url, String suggestedFilename, String mimeType, long contentLength, String contentDisposition, String userAgent);
void onExternalPageRequest(String url);
}
public static final String PACKAGE_NAME_DOWNLOAD_MANAGER = "com.android.providers.downloads";
protected static final int REQUEST_CODE_FILE_PICKER = 51426;
protected static final String DATABASES_SUB_FOLDER = "/databases";
protected static final String LANGUAGE_DEFAULT_ISO3 = "eng";
protected static final String CHARSET_DEFAULT = "UTF-8";
/**
* Alternative browsers that have their own rendering engine and *may* be installed on this device
*/
protected static final String[] ALTERNATIVE_BROWSERS = new String[]{"org.mozilla.firefox", "com.android.chrome", "com.opera.browser", "org.mozilla.firefox_beta", "com.chrome.beta", "com.opera.browser.beta"};
protected WeakReference<Activity> mActivity;
protected WeakReference<Fragment> mFragment;
protected Listener mListener;
protected final List<String> mPermittedHostnames = new LinkedList<String>();
/**
* File upload callback for platform versions prior to Android 5.0
*/
protected ValueCallback<Uri> mFileUploadCallbackFirst;
/**
* File upload callback for Android 5.0+
*/
protected ValueCallback<Uri[]> mFileUploadCallbackSecond;
protected long mLastError;
protected String mLanguageIso3;
protected int mRequestCodeFilePicker = REQUEST_CODE_FILE_PICKER;
protected WebViewClient mCustomWebViewClient;
protected WebChromeClient mCustomWebChromeClient;
protected boolean mGeolocationEnabled;
protected String mUploadableFileTypes = "*/*";
protected final Map<String, String> mHttpHeaders = new HashMap<String, String>();
public MyWebView(Context context) {
super(context);
init(context);
}
public MyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public void setListener(final Activity activity, final Listener listener) {
setListener(activity, listener, REQUEST_CODE_FILE_PICKER);
}
public void setListener(final Activity activity, final Listener listener, final int requestCodeFilePicker) {
if (activity != null) {
mActivity = new WeakReference<Activity>(activity);
} else {
mActivity = null;
}
setListener(listener, requestCodeFilePicker);
}
public void setListener(final Fragment fragment, final Listener listener) {
setListener(fragment, listener, REQUEST_CODE_FILE_PICKER);
}
public void setListener(final Fragment fragment, final Listener listener, final int requestCodeFilePicker) {
if (fragment != null) {
mFragment = new WeakReference<Fragment>(fragment);
} else {
mFragment = null;
}
setListener(listener, requestCodeFilePicker);
}
protected void setListener(final Listener listener, final int requestCodeFilePicker) {
mListener = listener;
mRequestCodeFilePicker = requestCodeFilePicker;
}
@Override
public void setWebViewClient(final WebViewClient client) {
mCustomWebViewClient = client;
}
@Override
public void setWebChromeClient(final WebChromeClient client) {
mCustomWebChromeClient = client;
}
@SuppressLint("SetJavaScriptEnabled")
public void setGeolocationEnabled(final boolean enabled) {
if (enabled) {
getSettings().setJavaScriptEnabled(true);
getSettings().setGeolocationEnabled(true);
setGeolocationDatabasePath();
}
mGeolocationEnabled = enabled;
}
@SuppressLint("NewApi")
protected void setGeolocationDatabasePath() {
final Activity activity;
if (mFragment != null && mFragment.get() != null && Build.VERSION.SDK_INT >= 11 && mFragment.get().getActivity() != null) {
activity = mFragment.get().getActivity();
} else if (mActivity != null && mActivity.get() != null) {
activity = mActivity.get();
} else {
return;
}
getSettings().setGeolocationDatabasePath(activity.getFilesDir().getPath());
}
public void setUploadableFileTypes(final String mimeType) {
mUploadableFileTypes = mimeType;
}
/**
* Loads and displays the provided HTML source text
*
* @param html the HTML source text to load
*/
public void loadHtml(final String html) {
loadHtml(html, null);
}
/**
* Loads and displays the provided HTML source text
*
* @param html the HTML source text to load
* @param baseUrl the URL to use as the page's base URL
*/
public void loadHtml(final String html, final String baseUrl) {
loadHtml(html, baseUrl, null);
}
/**
* Loads and displays the provided HTML source text
*
* @param html the HTML source text to load
* @param baseUrl the URL to use as the page's base URL
* @param historyUrl the URL to use for the page's history entry
*/
public void loadHtml(final String html, final String baseUrl, final String historyUrl) {
loadHtml(html, baseUrl, historyUrl, "utf-8");
}
/**
* Loads and displays the provided HTML source text
*
* @param html the HTML source text to load
* @param baseUrl the URL to use as the page's base URL
* @param historyUrl the URL to use for the page's history entry
* @param encoding the encoding or charset of the HTML source text
*/
public void loadHtml(final String html, final String baseUrl, final String historyUrl, final String encoding) {
loadDataWithBaseURL(baseUrl, html, "text/html", encoding, historyUrl);
}
@SuppressLint("NewApi")
@SuppressWarnings("all")
public void onResume() {
if (Build.VERSION.SDK_INT >= 11) {
super.onResume();
}
resumeTimers();
}
@SuppressLint("NewApi")
@SuppressWarnings("all")
public void onPause() {
pauseTimers();
if (Build.VERSION.SDK_INT >= 11) {
super.onPause();
}
}
public void onDestroy() {
// try to remove this view from its parent first
try {
((ViewGroup) getParent()).removeView(this);
} catch (Exception ignored) {
}
// then try to remove all child views from this view
try {
removeAllViews();
} catch (Exception ignored) {
}
// and finally destroy this view
destroy();
}
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
if (requestCode == mRequestCodeFilePicker) {
if (resultCode == Act