今天碰到这样一个问题,H5 要调用Android的相机和相册,点击没有反应,于是查了一下资料Android需要自己处理,iOS却是没问题,坑啊坑。
解决方案
public class MyWebChromeClient extends WebChromeClient {
public void openFileChooser(ValueCallback valueCallback) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
@Override
public void openFileChooser(ValueCallback valueCallback, String acceptType, String capture) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback valueCallback, FileChooserParams fileChooserParams) {
uploadMessageAboveL = valueCallback;
openImageChooserActivity();
return true;
}
}
private void openImageChooserActivity() {
avatarEditorDialog = new AvatarEditorDialog(this);
avatarEditorDialog.setOnClickListener(this);
avatarEditorDialog.show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_CHOOSER_RESULT_CODE && resultCode == RESULT_OK) {
if (null == uploadMessage && null == uploadMessageAboveL) return;
Uri result = data == null ? null : data.getData();
Log.e("linksu InnerWebViewAct",
"onActivityResult(InnerWebViewAct.java:154) result --> " + result.toString());
if (uploadMessageAboveL != null) {
onActivityResultAboveL(requestCode, resultCode, data);
} else if (uploadMessage != null) {
result = ImageUtil.geturi(data, this);
if (result == null) {
return;
}
uploadMessage.onReceiveValue(result);
uploadMessage = null;
}
} else if (requestCode == PHOTO_FILE_CHOOSER_RESULT_CODE && resultCode == RESULT_OK) {
Uri uri = null;
File file = new File(cameraUri.getPath());
if (!file.exists()) {
cameraUri = Uri.parse("");
}
ImageUtil.afterOpenCamera(imagePaths, this);
uri = cameraUri;
if (uploadMessageAboveL != null) {
Uri[] uris = new Uri[1];
uris[0] = uri;
uploadMessageAboveL.onReceiveValue(uris);
} else if (uploadMessage != null) {
uploadMessage.onReceiveValue(uri);
uploadMessage = null;
}
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
if (uploadMessageAboveL != null) {
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (intent != null) {
String dataString = intent.getDataString();
ClipData clipData = intent.getClipData();
if (clipData != null) {
results = new Uri[clipData.getItemCount()];
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
results[i] = item.getUri();
}
}
if (dataString != null)
results = new Uri[]{Uri.parse(dataString)};
}
}
uploadMessageAboveL.onReceiveValue(results);
uploadMessageAboveL = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
webView.destroy();
}
@Override
public void onClick(View v) {
super.onClick(v);
switch (v.getId()) {
case R.id.back:
if (webView.canGoBack()) {
webView.goBack();
}
break;
case R.id.btn_take_a_picture:
isXiangji = false;
if (Build.VERSION.SDK_INT < 23) {
if (PermissionCheckUtil.checkOp(InnerWebViewAct.this, 26)) {
openCapture();
} else {
checkCamraPermission();
}
} else {
MPermissions.requestPermissions(InnerWebViewAct.this, REQUECT_CODE_SDCARD, Manifest.permission.CAMERA);
}
break;
case R.id.btn_select_photo:
isXiangji = true;
if (Build.VERSION.SDK_INT < 23) {
if (PermissionCheckUtil.checkOp(InnerWebViewAct.this, 26)) {
openPick();
} else {
checkCamraPermission();
}
} else {
MPermissions.requestPermissions(InnerWebViewAct.this, REQUECT_CODE_SDCARD, Manifest.permission.CAMERA);
}
break;
case R.id.btn_cancel:
avatarEditorDialog.dismiss();
break;
}
}
@PermissionGrant(REQUECT_CODE_SDCARD)
public void requestSdcardSuccess() {
if (isXiangji) {
openPick();
} else {
openCapture();
}
}
@PermissionDenied(REQUECT_CODE_SDCARD)
public void requestSdcardFailed() {
Toast.makeText(this, "请您开启相机权限", Toast.LENGTH_SHORT).show();
checkCamraPermission();
}
/**
* 打开相册
*/
private void openPick() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
avatarEditorDialog.dismiss();
}
/**
* 打开照相机拍照
*/
private void openCapture() {
Intent take_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imagePaths = Environment.getExternalStorageDirectory().getPath()
+ "/fuiou_wmp/temp/"
+ (System.currentTimeMillis() + ".jpg");
// 必须确保文件夹路径存在,否则拍照后无法完成回调
File vFile = new File(imagePaths);
if (!vFile.exists()) {
File vDirPath = vFile.getParentFile();
vDirPath.mkdirs();
} else {
if (vFile.exists()) {
vFile.delete();
}
}
cameraUri = Uri.fromFile(vFile);
take_intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
startActivityForResult(take_intent, PHOTO_FILE_CHOOSER_RESULT_CODE);
avatarEditorDialog.dismiss();
}
注意Android 6.0 需要权限的判断
/**
* 拍照结束后
*/
public static void afterOpenCamera(String imagePaths, Context context) {
File f = new File(imagePaths);
addImageGallery(f, context);
}
/**
* 解决拍照后在相册中找不到的问题
*/
public static void addImageGallery(File file, Context context) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
/**
* 解决小米手机上获取图片路径为null的情况
*
* @param intent
* @return
*/
public static Uri geturi(Intent intent,Context context) {
Uri uri = intent.getData();
String type = intent.getType();
if (null != uri && null != type) {
if (uri.getScheme().equals("file") && (type.contains("image/"))) {
String path = uri.getEncodedPath();
if (path != null) {
path = Uri.decode(path);
ContentResolver cr = context.getContentResolver();
StringBuffer buff = new StringBuffer();
buff.append("(").append(MediaStore.Images.ImageColumns.DATA).append("=")
.append("'" + path + "'").append(")");
Cursor cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.ImageColumns._ID},
buff.toString(), null, null);
int index = 0;
for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
index = cur.getColumnIndex(MediaStore.Images.ImageColumns._ID);
index = cur.getInt(index);
}
if (index == 0) {
// do nothing
} else {
Uri uri_temp = Uri.parse("content://media/external/images/media/" + index);
if (uri_temp != null) {
uri = uri_temp;
}
}
}
}
}
return uri;
}
上面的代码,不得不适配各种兼容性,在Android <4.0 >= 5.0 >= 6.0 都没问题了。