Android三方库--TakePhoto与融云IM的相机调用闪退

对与app调用相机或相册上传头像到服务器除了最原始的写法外,还有一个神奇的第三方TakePhoto 和 Boxing

1.先来说说TakePhoto与融云的冲突,导致手机调用相机闪退:

错误信息如下:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference

其实,没有加入融云聊天的时候项目还是正常可以调用相机的,然而加入后就只可以调用相册,相机调用就闪退,找了半天才知道是添加file_paths.xml文件后,压缩失败,照片路径不对了,所以是空指针:

a.解决方法一:

新建一个RongFileProvider:

public class RongFileProvider extends android.support.v4.content.FileProvider {
}

对,你需要的就是上面的一个新建的空类而已,但它继承了FileProvider

然后在App内manifest内:

<provider
            android:name=".util.RongFileProvider"
            android:authorities="package包名.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true"
            tools:replace="name,authorities,exported,grantUriPermissions">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_path"
                tools:replace="name,resource"/>
        </provider>

这是第一种方法。

b.解决方法二:

在APP中引用IMKit的FileProvider直接注释掉,然后在takephoto的xml/file_paths.xml改成如下:

root-path path="" name="camera_photos"
external-path name="rc_external_path" path="."

2.TakePhoto简介:

用的人很多,案例很丰富:

compile 'com.jph.takephoto:takephoto_library:4.0.3'

Fragment去继承TakePhotoFragment ,然后继承三个监听方法:(注意:TResult的getCompressPath只有你使用压缩之后才能获取到,不然为null)

 /**
     * takePhoto的回调接口
     *
     * @param result
     */
    @Override
    public void takeSuccess(TResult result) {
        super.takeSuccess(result);
        TImage image = result.getImage();

    }

初始化配置:

// 初始化TakePhoto选取头像的配置
            TakePhoto takePhoto = getTakePhoto();
            CropOptions.Builder builder = new CropOptions.Builder();
            builder.setAspectX(800).setAspectY(800);
            builder.setWithOwnCrop(true);
            File file = new File(Environment.getExternalStorageDirectory(),
                    "/temp/" + System.currentTimeMillis() + ".jpg");
            if (!file.getParentFile().exists()) {
                boolean mkdirs = file.getParentFile().mkdirs();
                if (!mkdirs) {
                    ToastUtil.showShort("文件目录创建失败");
                }
            }
            Uri imageUri = Uri.fromFile(file);
            CompressConfig config = new CompressConfig.Builder()
                    .setMaxSize(102400)
                    .setMaxPixel(400)
                    .enableReserveRaw(true)
                    .create();
            takePhoto.onEnableCompress(config, true);

启动相册:

takePhoto.onPickFromDocumentsWithCrop(imageUri, builder.create());
 //相机获取照片并剪裁
            takePhoto.onPickFromCaptureWithCrop(imageUri, builderTake.create());
            //相机获取不剪裁
            //takePhoto.onPickFromCapture(uri);

启动相机:

takePhoto.onPickFromCaptureWithCrop(imageUri, builder.create());
 //多选,并剪裁
      takePhoto.onPickMultipleWithCrop(9, cropOptions);
      //多选,不剪裁
//      takePhoto.onPickMultiple(9);

实现两个接口:TakePhoto.TakeResultListener,InvokeListener

在 onCreate,onActivityResult,onSaveInstanceState方法中调用TakePhoto对用的方法

@Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    getTakePhoto().onCreate(savedInstanceState);
    super.onCreate(savedInstanceState);
  }

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

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    getTakePhoto().onSaveInstanceState(outState);
    super.onSaveInstanceState(outState);
  }

重写TPermissionType invoke(InvokeParam invokeParam)方法,添加如下代码:

@Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    //以下代码为处理Android6.0、7.0动态权限所需
    PermissionManager.TPermissionType type=PermissionManager.onRequestPermissionsResult(requestCode,permissions,grantResults);
    PermissionManager.handlePermissionsResult(this,type,invokeParam,this);
  }

  @Override
  public PermissionManager.TPermissionType invoke(InvokeParam invokeParam) {
    PermissionManager.TPermissionType type=PermissionManager.checkPermission(TContextWrap.of(this),invokeParam.getMethod());
    if(PermissionManager.TPermissionType.WAIT.equals(type)){
      this.invokeParam=invokeParam;
    }
    return type;
  }

调用不同的方法,常用的:相机,相册,多选

flag = getIntent().getIntExtra("flag", 0);
    File file = new File(getExternalCacheDir(), System.currentTimeMillis() + ".png");
    Uri uri = Uri.fromFile(file);
    int size = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
    CropOptions cropOptions = new CropOptions.Builder().setOutputX(size).setOutputX(size).setWithOwnCrop(false).create();
    if (flag == 1) {
      //相机获取照片并剪裁
      takePhoto.onPickFromCaptureWithCrop(uri, cropOptions);
      //相机获取不剪裁
      //takePhoto.onPickFromCapture(uri);
    } else if (flag == 2) {
      //相册获取照片并剪裁
      takePhoto.onPickFromGalleryWithCrop(uri, cropOptions);
      //相册获取不剪裁
//      takePhoto.onPickFromGallery();
    } else if (flag == 3) {
      //多选,并剪裁
      takePhoto.onPickMultipleWithCrop(9, cropOptions);
      //多选,不剪裁
//      takePhoto.onPickMultiple(9);
    }

前面一个页面调用startActivityForResult,传一个标记过来,用来判断调用不同的方式。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值