Android在H5中访问相机与相册

有时候我们需要在H5中调用Android的相机与相册,前段时间项目中用到了,鼓捣了一波。

老样子,拷贝代码就好使!

首先整个工具类,先访问一下相机权限:

public class Authority {

    private static final int MY_PERMISSION_REQUEST_CODE = 10000;
    //申请的权限,字符串模式
    public static final String CALL_PHONE = Manifest.permission.CALL_PHONE;//打电话权限
    public static final String CAMERA = Manifest.permission.CAMERA;//相机摄像头权限
    public static final String READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE;//读取内存卡权限
    public static final String WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;//写入内存卡权限

    //申请的权限,数组模式
    public static final String[] CALL_PHONE_ARR = {Manifest.permission.CALL_PHONE};//打电话权限
    public static final String[] CAMERA_ARR = {Manifest.permission.CAMERA};//相机摄像头权限
    public static final String[] READ_EXTERNAL_STORAGE_ARR = {Manifest.permission.READ_EXTERNAL_STORAGE};//读取内存卡权限
    public static final String[] WRITE_EXTERNAL_STORAGE_ARR = {Manifest.permission.WRITE_EXTERNAL_STORAGE};//写入内存卡权限

    //权限数组
    public static final String[] str = {
            Manifest.permission.CALL_PHONE,//打电话
            Manifest.permission.CAMERA, //相机
//            Manifest.permission.ACCESS_NETWORK_STATE,//网络
//            Manifest.permission.ACCESS_WIFI_STATE,//wifi
//            Manifest.permission.CHANGE_WIFI_STATE,//wifi
//            Manifest.permission.INTERNET,//网络
            Manifest.permission.READ_EXTERNAL_STORAGE,//获取sd
            Manifest.permission.WRITE_EXTERNAL_STORAGE//写入sd
    };

    //申请权限,多项申请(Activity)
    public static void CallMobile(Activity mContext) {
        ActivityCompat.requestPermissions(
                mContext,
                str,
                MY_PERMISSION_REQUEST_CODE//回调的标识
        );
    }

    //申请权限,单项权限,(Activity)
    public static void CallMobileArr(Activity mContext, String[] str) {
        ActivityCompat.requestPermissions(
                mContext,
                str,
                MY_PERMISSION_REQUEST_CODE//回调的标识
        );
    }

    //申请权限(fragment)
    //  requestPermissions(Authority.CAMERA_ARR, 10000);这种模式,不可以显示申请权限弹框.如果禁止所申请的权限,可以显示自定义弹框
    //下面这种模式:可以显示申请权限弹框.如果禁止所申请的权限,并且“下次不会再次提醒”已勾选,不会显示弹框
    @TargetApi(Build.VERSION_CODES.M)
    public static void CallMobileFragment(Activity mContext, String[] str) {
        mContext.requestPermissions(str, MY_PERMISSION_REQUEST_CODE);
    }


    //判断权限是否申请通过
    public static boolean lacksPermission(Context mContexts, String permission) {
        return ContextCompat.checkSelfPermission(mContexts, permission) ==
                PackageManager.PERMISSION_DENIED;
    }


    /**
     * @param s                  提示语
     * @param applicationContext 上下文
     * @param type               类型,是否关闭页面 1关闭,0不关闭
     */
    public static void openAppDetails(String s, final Activity applicationContext, final int type) {
        final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(applicationContext);
        builder.setMessage(s);
        builder.setCancelable(false);
        builder.setPositiveButton("去手动授权", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.setData(Uri.parse("package:" + applicationContext.getPackageName()));
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                applicationContext.startActivity(intent);
                if (type == 1) {
                    applicationContext.finish();
                }

            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                if (type == 1) {
                    applicationContext.finish();
                }
            }
        });
        builder.show();
    }

    //设置popu背景色
    public static void setBackgroundAlpha(float bgAlpha, Activity mContext) {
        WindowManager.LayoutParams lp = mContext.getWindow()
                .getAttributes();
        lp.alpha = bgAlpha;
        mContext.getWindow().setAttributes(lp);
    }
}

然后是Activity部分,申请相机权限:

Authority.CallMobileArr(LiangFangActivity.this, new String[]{Manifest.permission.CAMERA});

相机权限的回调

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 10000) {
        int isClose = 0;
        for (int i = 0; i < permissions.length; i++) {
            if (permissions[i].equals(Manifest.permission.CAMERA) || permissions[i].equals(Manifest.permission.READ_EXTERNAL_STORAGE) || permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                if (grantResults[i] == -1) {
                    isClose = 1;
                    final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(LiangFangActivity.this);
                    builder.setMessage("摄像头权限和存储权限为必要的权限。\n由于您拒绝了,这导致您无法正常使用该应用。");
                    builder.setCancelable(false);
                    builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            LiangFangActivity.this.finish();
                        }
                    });
                    builder.show();
                }
            }
        }
    }
}

下面正文部分

写了个方法,在onCreat方法里调用即可

private void setCheckImg() {
    mLiangFangWebView.setWebChromeClient(new WebChromeClient() {
        // For Android < 3.0
        public void openFileChooser(ValueCallback<Uri> valueCallback) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }

        // For Android  >= 3.0
        public void openFileChooser(ValueCallback valueCallback, String acceptType) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }

        //For Android  >= 4.1
        public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }

        // For Android >= 5.0
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
            uploadMessageAboveL = filePathCallback;
            openImageChooserActivity();
            return true;
        }
    });
}

然后选择弹出了一个选择框,相机还是相册

    private void openImageChooserActivity() {
        AlertDialog dialog = new AlertDialog.Builder(this)
                .setMessage("请选择")
                .setPositiveButton("相机", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        time = Calendar.getInstance().getTimeInMillis();


//                        file = new File(Environment.getExternalStorageDirectory().getPath()+"/", time + ".jpg");
                        pathTakePhoto = Environment.getExternalStorageDirectory().getPath()
                                + "/mbossclient/camera/temp/"
                                + (System.currentTimeMillis() + ".jpg");
                        File vFile = new File(pathTakePhoto);
                        if (!vFile.exists()) {
                            File vDirPath = vFile.getParentFile();
                            vDirPath.mkdirs();
                            Log.e("alshdkash", "onClick: " + vFile.getPath());
                        } else {
                            if (vFile.exists()) {
                                vFile.delete();
                            }
                        }
                        //App是一个继承Application的类,此处是需要获取一个全局的上下文即可
                        photoURI = FileProvider.getUriForFile(LiangFangActivity.this, App.context.getApplicationContext().getPackageName() + ".provider", vFile);
//        uriTakePhoto = Uri.fromFile(vFile);
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                        startActivityForResult(intent, FILE_CHOOSER_RESULT_CODE1);

                    }
                }).setNegativeButton("相册", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                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);
            }
        }).create();
        dialog.show();
        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                cancelFilePathCallback();
            }
        });
    }

如果不选择的话,调用此方法。需要一个返回值,没有返回值会导致无法再次调起相机相册,需要重新进入

private void cancelFilePathCallback() {
    if (uploadMessage != null) {
        uploadMessage.onReceiveValue(null);
        uploadMessage = null;
    } else if (uploadMessageAboveL != null) {
        uploadMessageAboveL.onReceiveValue(null);
        uploadMessageAboveL = null;
    }
}

然后是相机,相册的回调

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == FILE_CHOOSER_RESULT_CODE) {
            if (null == uploadMessage && null == uploadMessageAboveL) {
                return;
            }
            Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
            if (uploadMessageAboveL != null) {
                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (uploadMessage != null) {
                uploadMessage.onReceiveValue(result);
                uploadMessage = null;
            }
        } else if (requestCode == FILE_CHOOSER_RESULT_CODE1) {

            if (uploadMessageAboveL != null) {
                Uri[] results2 = {photoURI};
                uploadMessageAboveL.onReceiveValue(results2);
                uploadMessageAboveL = null;
//                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (uploadMessage != null) {
                uploadMessage.onReceiveValue(photoURI);
                uploadMessage = null;
            }
        }
    }
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
    if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
        return;
    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;

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 在HTML5,可以利用JavaScript调用Android设备的相机相册。要实现这个功能,首先需要使用`<input>`标签来创建一个文件上传输入框,然后通过JavaScript来触发文件上传的事件。 ``` <input type="file" id="file-input" accept="image/*" capture> ``` 在上述代码,`accept`属性用于指定上传的文件类型为图片,而`capture`属性表示可以通过设备的相机来拍照。 然后,在JavaScript添加以下代码,当点击上传输入框时,弹出相机相册选择: ``` document.getElementById("file-input").addEventListener("click", function() { if (navigator.camera) { // 检测是否支持Camera API navigator.camera.getPicture(onSuccess, onFail, { quality: 50, destinationType: Camera.DestinationType.FILE_URI, sourceType: Camera.PictureSourceType.PHOTOLIBRARY // 选择相册 }); } else { alert("此设备不支持相机功能"); } }); function onSuccess(imageURI) { // 在成功获取图片后的处理逻辑 } function onFail(message) { // 获取图片失败时的处理逻辑 alert('获取图片失败: ' + message); } ``` 以上代码,我们通过`navigator.camera.getPicture`方法来调用Android设备的相机相册,可以设置参数来控制图片的质量、目标类型和来源类型。`onSuccess`函数用于在成功获取图片时进行处理,而`onFail`函数则用于在获取图片失败时进行处理。 这样,当用户点击上传输入框时,会弹出相机相册的选择,用户可以拍照或从相册选择图片进行上传。 ### 回答2: 要在H5调用Android的弹框相机相册,可以通过以下步骤实现: 1. 在H5页面,使用Javascript监听触发事件,例如点击一个按钮。 2. 在触发事件的回调函数,通过Javascript与Android端进行通信,调用Android相机相册功能。可以使用WebView的addJavascriptInterface()方法创建一个Java对象,用于Javascript与Android端的交互。 3. 在Java对象,实现调用Android相机相册的代码逻辑。可以通过Intent启动Android相机相册应用,并在回调获取所选图片的路径或相机拍摄的照片数据。 4. 接收到图片路径或数据后,可以通过Javascript回调函数将获取的图片展示在H5页面上。 需要注意的是,调用Android相机相册需要申请相应权限,例如相机权限访问外部存储器权限。同时,还需要处理Android不同版本的兼容性问题,如Android 6.0以上需要动态申请权限。另外,还需要注意Android设备的厂商定制和系统版本的差异可能导致一些兼容性问题。 总之,通过以上步骤,可以在H5页面调用Android的弹框相机相册,实现拍照和选择图片的功能。 ### 回答3: 在H5页面可以通过调用Android相机相册来实现弹框拍照和选择照片的功能。具体的实现步骤如下: 1. 首先,在H5页面添加一个按钮或者其他的触发元素,用于触发调用相机相册的功能。 2. 在按钮的点击事件,使用JavaScript与Android的交互方法,例如使用Webview的`addJavascriptInterface`方法,将一个JavaScript对象注入到Android。 3. 在注入的JavaScript对象,定义一个方法,用于调用Android相机相册。可以通过Android的`Intent`来实现,调用相机的代码如下: ```java private static final int REQUEST_CAMERA = 1; public void openCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, REQUEST_CAMERA); } ``` 调用相册的代码如下: ```java private static final int REQUEST_GALLERY = 2; public void openGallery() { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, REQUEST_GALLERY); } ``` 4. 在Android,通过`onActivityResult`方法来处理相机相册的返回结果。可以在其获取到用户拍摄的照片或选择的照片的Uri。 5. 将获取到的照片Uri返回给H5页面,可以通过调用JavaScript的方法,在Android使用`WebView`的`loadUrl`方法执行JavaScript代码,来实现将照片Uri传递给H5页面。 通过以上步骤,H5页面就可以调用Android相机相册,并将拍摄的照片或选择的照片显示在页面上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值