美文网首页
Android中使用空白Fragment封装系统相机调用功能总结

Android中使用空白Fragment封装系统相机调用功能总结

作者: d41f12d62517 | 来源:发表于2019-04-23 23:15 被阅读0次

    之前运用过Fragment对Android动态运行时权限进行封装,避免了每次都需要onRequestPermissionsResult 回调处理。同理,也可以用同样的方式对 Activity的onActivityResult 回调进行封装。常用的想到了调用系统相机进行拍摄以及获取系统相册的图片。

    RouterFragment 中间层

    RouterFragment 起到一个中间层的作用。主要用来发起请求和接收回调,通过回调接口,将数据结果回调到调用类。先来看看 RouterFragment 主要代码。

    1. createRequestCode
      随机生成一定范围内的code,用于和回调的Callback进行一对一的缓存
        private int createRequestCode() {
            int requestCode;
            int tryCount = 0;
            do {
                requestCode = mCodeGenerator.nextInt(0x0000FFFF);
                tryCount++;
            } while (mCallBacks.indexOfKey(requestCode) >= 0 && tryCount < MAX_TRY_COUNT);
    
            return requestCode;
        }
    
    1. startActivityforResult
      调用跳转的地方,并且将Callback进行缓存
        public void startActivityforResult(Intent intent, CaptureHelper.Callback callback){
            int requestCode = createRequestCode();
            mCallBacks.put(requestCode, callback);
            startActivityForResult(intent, requestCode);
        }
    
    1. onActivityResult
      这个就是关键要处理的地方了,取出之前缓存的Callback,将请求结果回调到对应的code的请求中。
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            CaptureHelper.Callback callback = mCallBacks.get(requestCode);
            mCallBacks.remove(requestCode);
            if (callback != null) {
                callback.onActivityResult(requestCode, resultCode, data);
            }
        }
    

    CaptureHelper

    该类主要用于处理相机调用和系统相册的调用

    之前在用封装好的运行时权限库的时候,leakcanary 报出了Activity引用内存泄漏的风险,所以在Activity引用中使用了 弱引用进行优化。

       public CaptureHelper init(FragmentActivity activity){
            mWeakActivityRef = new WeakReference<>(activity);
            return SingletonHolder.INSTANCE;
        }
    
    开启系统相机进行拍照 requestCapture

    调用同时也考虑了对7.0系统的适配兼容。(7.0相机适配网上很多,这里就不细说了)
    直接上代码:

       /**
         * 打开相机进行拍照
         * @param savePath
         */
        public void requestCapture(String savePath){
    
            final File captureFile = new File(savePath);
    
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    
            Uri photoURI = null;
    
            if(captureFile != null){
    
                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
                    photoURI = FileProvider.getUriForFile(mWeakActivityRef.get(),
                            "com.qhh.baselib.image.provider",
                            captureFile);
                    //这段代码主要是拍照之后保存在临时路径上
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                    intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
                    intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
                    intent.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION);
                }else{
                    //7.0以下使用这种方式创建一个Uri
                    photoURI = Uri.fromFile(captureFile);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                    intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
                }
    
            }
    
            //通过中间层的Fragment请求并且回调数据,最终在工具类中再往上层进行回调
            getFragment().startActivityforResult(intent, new Callback() {
                @Override
                public void onActivityResult(int requestCode, int resultCode, Intent data) {
                    if(resultCode == RESULT_OK){
                        String path = captureFile.getAbsolutePath();
                        if(mIRequestCaptureCallback != null)
                            mIRequestCaptureCallback.success(resultCode,path);
                    }else{
                        if(mIRequestCaptureCallback != null)
                            mIRequestCaptureCallback.error(resultCode);
                    }
    
                }
            });
    
    
    getFragment 主要用于获取中间层的Fragment
        private RouterFragment getFragment(){
            FragmentManager manager = mWeakActivityRef.get().getSupportFragmentManager();
            RouterFragment fragment = (RouterFragment)manager.findFragmentByTag(REQUEST_CAPTURE);
    
            if(fragment == null){
                fragment = RouterFragment.getInstance();
                manager.beginTransaction()
                        .add(fragment,REQUEST_CAPTURE)
                        .commitAllowingStateLoss();
                manager.executePendingTransactions();
            }
    
            return fragment;
        }
    

    最后

    上边主要是简单的展示代码,实现原理比较的简单,通过封装可以以后自己用的时候方便一些,最后放到了Jitpack上。详细的使用可以参考我github上的源码和readme。
    https://github.com/qinhaihang/BaseLib

    相关文章

      网友评论

          本文标题:Android中使用空白Fragment封装系统相机调用功能总结

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