今天写Android打开相机获取路径的心得体会 大大的坑啊

android7.0调用相机拍照的问题解决方案

最近在应用中开发调用系统相机拍照的时候,遇到一个问题,就是在安卓7.0及以上机型使用,按照往常写法Uri.fromFile(imgFile)回抛出异常FileUriExposedException导致程序崩溃。通过上网查看知道了安卓7.0及以上的特殊问题。因此整理了其他的人的处理方法,我也根据自身的项目需要进行了整改,特此奉上,供学习交流!

1.在清单文件里添加provider如下:

<application
    ...>
       <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="包名.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"></meta-data>
        </provider>
</application>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.在res目录下新建xml文件夹,并新建一个file_paths.xml文件,内容如下

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>
  • 1
  • 2
  • 3
  • 4

具体什么意思,自行百度吧。我就是这么一个不求甚解的人。。。

3.配置算是完成,进入应用阶段。调用相机的方法:

 private void startCarmera(){
        File file = new File(getExternalCacheDir(), "img.jpg");
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
            intent.putExtra(MediaStore.EXTRA_OUTPUT,
                    FileProvider.getUriForFile(this,"包名.fileprovider", file));
        }else {
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
        }
        startActivityForResult(intent, TAKEPHOTO);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

然后是获取返回值:

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == TAKEPHOTO && resultCode == RESULT_OK) {
            //设置文件保存路径这里放在跟目录下
            File picture = new File(getExternalCacheDir() + "/img.jpg");
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
                Uri uri = FileProvider.getUriForFile(this, "包名.fileprovider", picture);
                //裁剪照片
                startPhotoZoom(uri);
            }else {
             //裁剪照片
                startPhotoZoom(Uri.fromFile(picture));
            }
        }

        // 裁剪照片的处理结果,看完后面的代码再看这里
        if (requestCode == PHOTORESULT) {
            Bundle extras = data.getExtras();
            File file = new File(getExternalCacheDir() + "/head.jpg");
            if (extras != null) {
                Bitmap photo = extras.getParcelable("data");
                try {
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
                    photo.compress(Bitmap.CompressFormat.JPEG, 70, bos);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                imgView.setImageBitmap(photo);
            }
            super.onActivityResult(requestCode, resultCode, data);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

一般拍完照片后我们会有一步裁剪的操作,在代码中我也添加了。因为针对安卓7.0及以上系统版本,也和过往系统不大一样。看代码:

// 剪裁图片
    public void startPhotoZoom(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");

    //这段代码判断,在安卓7.0以前版本是不需要的。特此注意。不然这里也会抛出异常
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
        intent.putExtra("circleCrop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectY", 1);
        intent.putExtra("aspectX", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 50);
        intent.putExtra("outputY", 50);
//        intent.putExtra("scale",true);//自由截取
        intent.putExtra("return-data", true);
        startActivityForResult(intent, PHOTORESULT);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

好了。具体就是这样了。由此我完美解决了安卓7.0及以上调用相机拍照导致程序崩溃的问题。另外,在安卓6.0及以上需要相机功能时,也是需要动态获取相应权限的,在此不再赘述。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值