美文网首页
H5 可以直接拍照--原生处理

H5 可以直接拍照--原生处理

作者: 勤劳的蚂蚁 | 来源:发表于2020-04-01 16:32 被阅读0次
    1. H5 可以直接拍照 通过 WebChromeClient 来处理
    // 辅助处理JavaScript、页喧解析渲染、页面标题、加载进度等等
                mWebView.setWebChromeClient(commonWebChromeClient);
    2. 重写 WebChromeClient 方法 onShowFileChooser 5.0 及以上和openFileChooser 4-5.0
    获取参数 这两对象接收拍照完后的流
       public ValueCallback<Uri> mUploadMessage;  5.0以下
       public ValueCallback<Uri[]> uploadMessage; 5.0 及其以上
    3. 拍照调用
      Intent takeIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
           //下面这句指定调用相机拍照后的照片存储的路径
      takeIntent.putExtra (MediaStore.EXTRA_OUTPUT, Uri.fromFile (new File (mTempPhotoPath)));
     startActivityForResult (takeIntent, REQUEST_SELECT_FILE);
    4.拍照结果回调
      拍照回传后的intent 数据为空
    需要对 path 进行处理
      5.0 及其以上
       uploadMessage.onReceiveValue (new Uri[]{Uri.fromFile (new File (mTempPhotoPath))});
        uploadMessage = null;
      5.0以下:
       Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData ();
                    if (result == null) {
    //多操作了一步
                        Uri[] ll = new Uri[]{Uri.fromFile (new File (mTempPhotoPath))};
                        if (ll != null && ll.length > 0) {
                            result = ll[0];
                        }
                    }
                    mUploadMessage.onReceiveValue (result);
                    mUploadMessage = null;
    
    
    

    5.0及以下 获取Uri 的方法是否只有这一种??
    File file = new File(PictureUtil.bitmapToPath(sourcePath));
    Uri uri = Uri.fromFile(file);

    拓展
    https://www.jianshu.com/p/c9b383caab02

    其他方法:
    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);

    文件:Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.addCategory(Intent.CATEGORY_OPENABLE);
    i.setType("image/");
    startActivityForResult(Intent.createChooser(i, "File Browser"), RESULTCODE);
    ??
    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);

    相册 :Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(pickIntent, CODE);

    9 Intent.ACTION_CHOOSER
    String: android.intent.action.CHOOSER显示一个activity选择器,允许用户在进程之前选择他们想要的,与之对应的是Intent.ACTION_GET_CONTENT.
    
    10. Intent.ACTION_GET_CONTENT
    String: android.intent.action.GET_CONTENT允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)
    Input: TypeOutput:URI
    
    int requestCode = 1001;
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"
    intent.setType("image/*"); // 查看类型,如果是其他类型,比如视频则替换成 video/*,或 */*
    Intent wrapperIntent = Intent.createChooser(intent, null);
    startActivityForResult(wrapperIntent, requestCode);
    
    //拍照     REQUEST_CODE_TAKE_PICTURE 为返回的标识
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //"android.media.action.IMAGE_CAPTURE";
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Mms.ScrapSpace.CONTENT_URI); // output,Uri.parse("content:/s/scrapSpace");
    startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
    
    //添加音视频
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType(contentType); //String VIDEO_UNSPECIFIED = "video/*";
    Intent wrapperIntent = Intent.createChooser(intent, null);
    ((Activity) context).startActivityForResult(wrapperIntent, requestCode);
    
    //拍摄视频
    
    int durationLimit = getVideoCaptureDurationLimit(); //SystemProperties.getInt("ro.media.enc.lprof.duration", 60);
    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
    intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, sizeLimit);
    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationLimit);
    startActivityForResult(intent, REQUEST_CODE_TAKE_VIDEO);
    
    
    //录音
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType(ContentType.AUDIO_AMR); //String AUDIO_AMR = "audior";
    intent.setClassName("com.android.soundrecorder",
    "com.android.soundrecorder.SoundRecorder");
    ((Activity) context).startActivityForResult(intent, requestCode);
    
    
    
    
    Activity 或者Fragment
    mPermissionHelper 为android 6.0权限 处理的类
    
       public ValueCallback<Uri> mUploadMessage;
       public ValueCallback<Uri[]> uploadMessage;
       private String mTempPhotoPath;//拍照照片路径
    
    onCreate(){//处理路径逻辑
        initPhotoPath();
    }
    
    
     //添加权限判断   H5调用原生拍照
        private void initPhotoPath() {
            if (mPermissionHelper != null) {
                Map<String, String> permissionMap1 = new HashMap<> ();
                permissionMap1.put (Manifest.permission.WRITE_EXTERNAL_STORAGE, AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE);
                if (mPermissionHelper.hasPermiss1 (getActivity (), permissionMap1)) {
                    if (Environment.MEDIA_MOUNTED.equals (Environment.getExternalStorageState ())) {//如果已经挂载
                        //sd卡已经挂载,可以进行读写操作了
                        mTempPhotoPath = Environment.getExternalStorageDirectory () + File.separator + System.currentTimeMillis () / 1000 + ".jpeg";
    
                    } else {
                        //sd卡无挂载,使用内置存储卡
                        mTempPhotoPath = this.getActivity ().getFilesDir () + File.separator + System.currentTimeMillis () / 1000 + ".jpeg";
                    }
                } else {
                    //使用内置存储卡,可以进行读写操作了
                    mTempPhotoPath = this.getActivity ().getFilesDir () + File.separator + System.currentTimeMillis () / 1000 + ".jpeg";
                }
            }
    
        }
      @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            switch (requestCode) {
                case REQUEST_SELECT_FILE://H5调用原生拍照
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        onActivityResultAboveL (requestCode, resultCode, data);
                    } else {
                        onActivityResultDown (requestCode, resultCode, data);
                    }
                    break;
                default:
                    break;
    
            }
       
        }
    
      
        //android 5.0 及其以上  H5调用原生拍照
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
            //如果没有接受者
            if (uploadMessage == null) {//没有接受者
                return;
            }
            //如果结果码为取消
            if (resultCode == RESULT_CANCELED) {
                cancelCallback ();
                return;
            }
    
            switch (requestCode) {
                case REQUEST_SELECT_FILE://拍照
                    uploadMessage.onReceiveValue (new Uri[]{Uri.fromFile (new File (mTempPhotoPath))});
                    uploadMessage = null;
                    break;
                default:
                    Uri[] results = null;
                    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)};
                        }
                    }
                    uploadMessage.onReceiveValue (results);
                    uploadMessage = null;
                    break;
            }
    
        }
    
        //android 5.0 以下  H5调用原生拍照
        private void onActivityResultDown(int requestCode, int resultCode, Intent intent) {
            //如果没有接受者
            if (null == mUploadMessage) {
                return;
            }
            //如果结果码为取消
            if (resultCode == RESULT_CANCELED) {
                cancelCallback ();
                return;
            }
    
            switch (requestCode) {
                case REQUEST_SELECT_FILE://拍照
                    // Use MainActivity.RESULT_OK if you're implementing WebView inside Fragment
                    // Use RESULT_OK only if you're implementing WebView inside an Activity
                    Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData ();
                    if (result == null) {
                        Uri[] ll = new Uri[]{Uri.fromFile (new File (mTempPhotoPath))};
                        if (ll != null && ll.length > 0) {
                            result = ll[0];
                        }
    
                    }
                    mUploadMessage.onReceiveValue (result);
                    mUploadMessage = null;
                    break;
                default:
                    Uri result1 = (intent == null ? null : intent.getData());
                    mUploadMessage.onReceiveValue(result1);
                    mUploadMessage=null;
                    break;
            }
    
        }
    
        //添加权限判断   H5调用原生拍照
        private void initPhotoPath() {
            if (mPermissionHelper != null) {
                Map<String, String> permissionMap1 = new HashMap<> ();
                permissionMap1.put (Manifest.permission.WRITE_EXTERNAL_STORAGE, AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE);
                if (mPermissionHelper.hasPermiss1 (getActivity (), permissionMap1)) {
                    if (Environment.MEDIA_MOUNTED.equals (Environment.getExternalStorageState ())) {//如果已经挂载
                        //sd卡已经挂载,可以进行读写操作了
                        mTempPhotoPath = Environment.getExternalStorageDirectory () + File.separator + System.currentTimeMillis () / 1000 + "s.jpeg";
    
                    } else {
                        //sd卡无挂载,使用内置存储卡
                        mTempPhotoPath = this.getActivity ().getFilesDir () + File.separator + System.currentTimeMillis () / 1000 + "s.jpeg";
                    }
                } else {
                    //使用内置存储卡,可以进行读写操作了
                    mTempPhotoPath = this.getActivity ().getFilesDir () + File.separator + System.currentTimeMillis () / 1000 + "s.jpeg";
                }
            }
    
        }
        //H5  默认拍照处理 H5调用原生拍照
        public void h5Capture() {
            if (mPermissionHelper == null) {
                mPermissionHelper = new PermissionHelper ();
            }
            Map<String, String> permissionMap1 = new HashMap<> ();
            permissionMap1.put (Manifest.permission.CAMERA, AppOpsManager.OPSTR_CAMERA);
            permissionMap1.put (Manifest.permission.WRITE_EXTERNAL_STORAGE, AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE);
            mPermissionHelper.checkPermission (getActivity (), new OnPermissionListener () {
                @Override
                public void OnPermissonResult(boolean agreed) {
                    if (agreed) {
                        try {
                            Intent takeIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
                            //下面这句指定调用相机拍照后的照片存储的路径
                            takeIntent.putExtra (MediaStore.EXTRA_OUTPUT, Uri.fromFile (new File (mTempPhotoPath)));
                            startActivityForResult (takeIntent, REQUEST_SELECT_FILE);
                        } catch (Exception e) {
                            MyToast.showShort ("禁止上传");
                        }
    
                    } else {
                        MyToast.showShort ("相机或存储权限被禁止,请在设置中开启拍照或存储权限");
                    }
                }
            }, permissionMap1);
        }
    
        /**
         *
         * H5调用原生拍照
         */
        public void cancelCallback() {
            if (mUploadMessage != null) {
                mUploadMessage.onReceiveValue (null);
                mUploadMessage = null;
            }
    
            if (uploadMessage != null) {
                uploadMessage.onReceiveValue (null);
                uploadMessage = null;
            }
        }
    
    
    
    
    public class CommonWebChromeClient extends WebChromeClient {
        private String LOG_TAG = "WebChromeClient";
        // 使用者提供的Context
        private WeakReference<WebviewFragment> mUserContext;
    
        public CommonWebChromeClient(WebviewFragment context) {
            mUserContext =new WeakReference (context) ;
        }
    
       
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
            try {
                String[] acceptTypes=fileChooserParams.getAcceptTypes ();
                String type="";
                if(acceptTypes!=null&&acceptTypes.length>0){
                    type=acceptTypes[0];
                }
    
                if (mUserContext.get ().uploadMessage != null) {
                    mUserContext.get ().uploadMessage.onReceiveValue (null);
                    mUserContext.get ().uploadMessage = null;
                }
                mUserContext.get ().uploadMessage = filePathCallback;
                //返回对实时媒体捕获值(例如照相机、麦克风)的首选项  True indicates capture is enabled, false disabled.
                //默认拍照
                //capture 可用与否
                if(fileChooserParams.isCaptureEnabled ()){
                    if(type.contains ("image")){//拍照
                        mUserContext.get ().h5Capture ();
                    }else if(type.contains ("video")){
    
                    }else if(type.contains ("audio")){
    
                    }else {//默认拍照
                        mUserContext.get ().h5Capture ();
                    }
                }else{//设备不可用,什么都不做  ---可以 处理为 相册
                    mUserContext.get ().uploadMessage.onReceiveValue (null);
                    mUserContext.get ().uploadMessage = null;
                }
    
             return true;
            } catch (Exception e) {
                e.printStackTrace ();
            }
            return super.onShowFileChooser (webView, filePathCallback, fileChooserParams);
        }
        //5.0 一下,3.0
        public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType) {
            try {
                mUserContext.get ().mUploadMessage = uploadFile;
                mUserContext.get ().h5Capture ();
            } catch (Exception e) {
                e.printStackTrace ();
            }
        }
        //5.0 一下,4.0 以上处理逻辑    针对 Android版本  > 4.1.1
        public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture) {
            try {
                mUserContext.get ().mUploadMessage = uploadFile;
                mUserContext.get ().h5Capture ();
                } catch (Exception e) {
                e.printStackTrace ();
            }
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:H5 可以直接拍照--原生处理

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