移动端Android知识Android知识点和文章分享

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

2017-05-17  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读