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

2019-04-23  本文已影响0人  d41f12d62517

之前运用过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

上一篇下一篇

猜你喜欢

热点阅读