混合开发-H5 调用Android 的相册和照相机上传图片的问题

今天碰到这样一个问题,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 都没问题了。

你可能感兴趣的:(混合开发-H5 调用Android 的相册和照相机上传图片的问题)