美文网首页移动端Android知识Android知识点和文章分享
解决 Android 7.x相机拍照报 Android.os.F

解决 Android 7.x相机拍照报 Android.os.F

作者: 闹闹也会有脾气 | 来源:发表于2017-05-17 21:03 被阅读170次

    解决 Android 7.x 报错 Android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

    过去在Android 7.x之前的手机调用拍照直接简单的唤起系统相机

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    Uri uri = Uri.fromFile(sdcardTempFile);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

    但是Android N 文件系统权限的变化(Android N == Android 7.x);

    为了提高私有文件的安全性,在targetSdk版本为N或者以后版本的app中,其私有目录将会限制访问。这可以防止私有文件元数据的泄露,比如文件大小或者是文件是否存在。但这给开发者带来了很多不利的影响;

    如果你的targetSdk版本为N,恭喜你

    解决方案:

    --- 使用FileProvider 能完美解决 ---

    1、在res资源目录下新建一个xml文件夹

    2、在xml目录下新建一 file_paths.xml,然后打开xml文件添加如下代码

    <?xml version="1.0"encoding="utf-8"?>

    <paths> 

        <external-path name="files_root"  path="Android/data/${你的包名}/"/>

        <external-path name="external_storage_root"  path="."/>

    </paths>

    3、在AndroidManifest.xml中添加如下代码

    <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"/>

    </provider>

    4、修改代码适配Android N,由于Android N对权限管理严格,所以呢要做权限处理

    如下代码内容 == 如上图显示:(由于没有格式化功能,所以可以直接复制进IDE 进行格式化跳整)

    public voidselectPicFromCamera() {

         if(!EaseCommonUtils.isExitsSdcard()) {

                showToast("SD卡不存在,不能拍照");

               return;

          }

         if(Build.VERSION.SDK_INT>=23) {

             int checkPermission = ContextCompat.checkSelfPermission(this,     Manifest.permission.CAMERA);  

             if(checkPermission != PackageManager.PERMISSION_GRANTED) {                                         ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},222);

    return;

     }else{ openCamera(); } }else{ openCamera(); } }


    @Override

    public voidonRequestPermissionsResult(intrequestCode, String[] permissions,int[] grantResults) {

       switch(requestCode) {

         //就像onActivityResult一样这个地方就是判断你是从哪来的。

         case 222:

                if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                      openCamera(); }else{  Toast.makeText(this,"很遗憾你把相机权限禁用了。请务必开启相机权限享受我们提供的服务吧。", Toast.LENGTH_SHORT).show(); }

           break;

           default:

           super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        } }


    //拍照

    private voidopenCamera() {

       cameraFile=newFile(PathUtil.getInstance().getImagePath(),         EMClient.getInstance().getCurrentUser() + System.currentTimeMillis() +".jpg");

       cameraFile.getParentFile().mkdirs();

       Intent intent =newIntent(MediaStore.ACTION_IMAGE_CAPTURE);

       //判断是否是AndroidN以及更高的版本

      if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) {

          Uri contentUri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID+".fileProvider",cameraFile);      intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);

    }else{  intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile)); }  startActivityForResult(intent, Constants.REQUEST_CODE.IMAGE_CAPTURE); }

    private void showToast(String c){ Toast.makeText(this,c,Toast.LENGTH_SHORT).show();  }

    亲测试完美解决

    方法二:使用ContentProvider方式传递uri,

    参考:http://blog.csdn.net/honjane/article/details/52057132

    相关文章

      网友评论

      本文标题:解决 Android 7.x相机拍照报 Android.os.F

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