首页 » Android » Android 7.0使用相机拍照,出现FileUriExposedException异常

Android 7.0使用相机拍照,出现FileUriExposedException异常

 

以前写的相机模块功能,在7.0手机上遇到错误,记录一下。

Android 7.0以下 调用方式

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
 + "/test/" + System.currentTimeMillis() + ".jpg");
file.getParentFile().mkdirs();
Uri uri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
7.0以后再使用上面的方式会出现FileUriExposedException异常错误。

Android 7.0以上调用方式

使用FileProvider来解决,FileProvider是ContentProvider的一个子类。

1.res目录新建xml文件夹,并新建xml\file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="image_file"
        path="Android/data/你的包名/files/Pictures"/>
</paths>
  • <files-path/>代表的根目录: Context.getFilesDir()
  • <external-path/>代表的根目录: Environment.getExternalStorageDirectory()
  • <cache-path/>代表的根目录: getCacheDir()

2.注册FileProvider

 <!-- 自定义URI 需要 provider -->
 <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>
3. 详细代码
/**
 * 拍照获取图片
 **/
public void take_photo() {
    //创建File对象,用于存储拍照后的图片
    File outputImage = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
         //external-path == Environment.getExternalStorageDirectory()
        outputImage = new File(Environment.getExternalStorageDirectory(), "output_image.jpg");
        try {
            if (outputImage.exists()) {
                outputImage.delete();
            }
            outputImage.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", outputImage);
    } else {
        outputImage = new File(getExternalCacheDir(), "output_image.jpg");
        try {
            if (outputImage.exists()) {
                outputImage.delete();
            }
            outputImage.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        uri = Uri.fromFile(outputImage);
    }
    //启动相机程序
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    startActivityForResult(intent, Constant.REQUEST_CODE_CAPTURE_CAMEIA);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == Constant.REQUEST_CODE_CAPTURE_CAMEIA && resultCode == RESULT_OK && uri != null) {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
              //创建File对象,用于存储拍照后的图片
              File outputImage = new File(Environment.getExternalStorageDirectory(), "output_image.jpg");
              filePath = outputImage.getAbsolutePath();
          }else{
              filePath = FileUtils.getRealFilePath(this, uri);
          }
              ImageUtils.getInstance().uploadImageToQiniu(filePath,QINIU_TOKEN,this);
    }
}

getRealFilePath的方法
public static String getRealFilePath(final Context context, final Uri uri) {
    if (null == uri) return null;
    final String scheme = uri.getScheme();
    String data = null;
    if (scheme == null)
        data = uri.getPath();
    else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
        data = uri.getPath();
    } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
        Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
        if (null != cursor) {
            if (cursor.moveToFirst()) {
                int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                if (index > -1) {
                    data = cursor.getString(index);
                }
            }
            cursor.close();
        }
    }
    return data;
}

关于FileProvider 具体可以去看一下https://developer.android.com/reference/android/support/v4/content/FileProvider.html

好像要用到梯子,有兴趣自建梯子的看可以看看教你自己怎么搭建SSR梯子实现网络自由.

原文链接:Android 7.0使用相机拍照,出现FileUriExposedException异常,转载请注明来源!

0