美文网首页Android OtherAndroid开发Android技术知识
混合开发-H5 调用Android 的相册和照相机上传图片的问题

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

作者: 289346a467da | 来源:发表于2017-08-01 10:24 被阅读375次

    今天碰到这样一个问题,H5 要调用Android的相机和相册,点击没有反应,于是查了一下资料Android需要自己处理,iOS却是没问题,坑啊坑。

    解决方案

    public class MyWebChromeClient extends WebChromeClient {
    
        public void openFileChooser(ValueCallback<Uri> valueCallback) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }
    
        public void openFileChooser(ValueCallback valueCallback, String acceptType) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }
    
    
        @Override
        public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }
    
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> 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 都没问题了。

    相关文章

      网友评论

      • 克拉丶:兄弟,看了那么多代码,就你写的像模像样,编译了一下成功了,我再加一个偏转修正,美滋滋
        289346a467da:额 。。 哈哈 好吧!

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

      本文链接:https://www.haomeiwen.com/subject/ybtjlxtx.html