Android WebView 选择图片
public static final int SELECT_IMAGE_REQUEST_CODE = 1000;
private WebView mWebView;
private ValueCallback<Uri[]> mValueCallback;
private void setWeb() {
mWebView.loadUrl(url);
WebSettings webSettings = mWebView.getSettings();
webSettings.setTextZoom(100);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setAppCacheEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadsImagesAutomatically(true);
webSettings.setAllowFileAccessFromFileURLs(true);
mWebView.setHorizontalScrollBarEnabled(false);
mWebView.setVerticalScrollBarEnabled(false);
mWebView.setWebChromeClient(new MyWebChromeClient());
}
class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, FileChooserParams fileChooserParams) {
resetWebSelectImageCallBack();
mValueCallback = valueCallback;
selectImage();
return true;
}
}
private void selectImage() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "Image Chooser"), SELECT_IMAGE_REQUEST_CODE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (SELECT_IMAGE_REQUEST_CODE == requestCode) {
if (RESULT_OK != resultCode) {
resetWebSelectImageCallBack();
return;
}
if (null != mValueCallback) {
Uri uri = data.getData();
mValueCallback.onReceiveValue(new Uri[]{UriUtils.file2Uri(UriUtils.uri2File(uri))});
mValueCallback = null;
}
}
}
private void resetWebSelectImageCallBack() {
if (null != mValueCallback) {
mValueCallback.onReceiveValue(null);
mValueCallback = null;
}
}
UriUtils
public static Uri file2Uri(@NonNull final File file) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
String authority = Utils.getApp().getPackageName() + ".utilcode.provider";
return FileProvider.getUriForFile(Utils.getApp(), authority, file);
} else {
return Uri.fromFile(file);
}
}
public static File uri2File(@NonNull final Uri uri) {
Log.d("UriUtils", uri.toString());
String authority = uri.getAuthority();
String scheme = uri.getScheme();
String path = uri.getPath();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& path != null) {
String[] externals = new String[]{"/external", "/external_path"};
for (String external : externals) {
if (path.startsWith(external + "/")) {
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ path.replace(external, ""));
if (file.exists()) {
Log.d("UriUtils", uri.toString() + " -> " + external);
return file;
}
}
}
}
if (ContentResolver.SCHEME_FILE.equals(scheme)) {
if (path != null) return new File(path);
Log.d("UriUtils", uri.toString() + " parse failed. -> 0");
return null;
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& DocumentsContract.isDocumentUri(Utils.getApp(), uri)) {
if ("com.android.externalstorage.documents".equals(authority)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return new File(Environment.getExternalStorageDirectory() + "/" + split[1]);
} else {
StorageManager mStorageManager = (StorageManager) Utils.getApp().getSystemService(Context.STORAGE_SERVICE);
try {
Class<?> storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getUuid = storageVolumeClazz.getMethod("getUuid");
Method getState = storageVolumeClazz.getMethod("getState");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isPrimary = storageVolumeClazz.getMethod("isPrimary");
Method isEmulated = storageVolumeClazz.getMethod("isEmulated");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
final boolean mounted = Environment.MEDIA_MOUNTED.equals(getState.invoke(storageVolumeElement))
|| Environment.MEDIA_MOUNTED_READ_ONLY.equals(getState.invoke(storageVolumeElement));
if (!mounted) continue;
if ((Boolean) isPrimary.invoke(storageVolumeElement)
&& (Boolean) isEmulated.invoke(storageVolumeElement)) {
continue;
}
String uuid = (String) getUuid.invoke(storageVolumeElement);
if (uuid != null && uuid.equals(type)) {
return new File(getPath.invoke(storageVolumeElement) + "/" + split[1]);
}
}
} catch (Exception ex) {
Log.d("UriUtils", uri.toString() + " parse failed. " + ex.toString() + " -> 1_0");
}
}
Log.d("UriUtils", uri.toString() + " parse failed. -> 1_0");
return null;
}
else if ("com.android.providers.downloads.documents".equals(authority)) {
final String id = DocumentsContract.getDocumentId(uri);
if (!TextUtils.isEmpty(id)) {
try {
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id)
);
return getFileFromUri(contentUri, "1_1");
} catch (NumberFormatException e) {
if (id.startsWith("raw:")) {
return new File(id.substring(4));
}
}
}
Log.d("UriUtils", uri.toString() + " parse failed. -> 1_1");
return null;
}
else if ("com.android.providers.media.documents".equals(authority)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
} else {
Log.d("UriUtils", uri.toString() + " parse failed. -> 1_2");
return null;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getFileFromUri(contentUri, selection, selectionArgs, "1_2");
}
else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
return getFileFromUri(uri, "1_3");
}
else {
Log.d("UriUtils", uri.toString() + " parse failed. -> 1_4");
return null;
}
}
else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
return getFileFromUri(uri, "2");
}
else {
Log.d("UriUtils", uri.toString() + " parse failed. -> 3");
return null;
}
}
private static File getFileFromUri(final Uri uri, final String code) {
return getFileFromUri(uri, null, null, code);
}
private static File getFileFromUri(final Uri uri,
final String selection,
final String[] selectionArgs,
final String code) {
final Cursor cursor = Utils.getApp().getContentResolver().query(
uri, new String[]{"_data"}, selection, selectionArgs, null);
if (cursor == null) {
Log.d("UriUtils", uri.toString() + " parse failed(cursor is null). -> " + code);
return null;
}
try {
if (cursor.moveToFirst()) {
final int columnIndex = cursor.getColumnIndex("_data");
if (columnIndex > -1) {
return new File(cursor.getString(columnIndex));
} else {
Log.d("UriUtils", uri.toString() + " parse failed(columnIndex: " + columnIndex + " is wrong). -> " + code);
return null;
}
} else {
Log.d("UriUtils", uri.toString() + " parse failed(moveToFirst return false). -> " + code);
return null;
}
} catch (Exception e) {
Log.d("UriUtils", uri.toString() + " parse failed. -> " + code);
return null;
} finally {
cursor.close();
}
}