混合开发-H5 调用Android(安卓)的相册和照相机上传图片的问题
16lz
2022-03-09
今天碰到这样一个问题,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();}@Overrideprotected 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; }}@Overrideprotected void onDestroy() { super.onDestroy(); webView.destroy();}@Overridepublic 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 都没问题了。
更多相关文章
- Android(安卓)IntentService问题
- 简单的 Android(安卓)拍照并显示以及获取路径后上传
- Android(安卓)解决帧动画卡顿问题
- Robotium学习笔记一
- Android中拍照、图片、录音、视频和音频功能的方法和代码
- Listview 中加上checbox 焦点问题
- Android中ListView的addFooterView不显示的有关问题和adapter
- Android(安卓)studio 启动模拟器时解决 VT-x is disabled in BIO
- Android(安卓)- Read Only File System IOException-目录问题