为捕获的图像创建单独的文件夹时出现 FileUriExposedException

FileUriExposedException when create separate folder for captured images

我正在尝试使用以下代码将相机拍摄的图像存储在单独的文件夹中,但是当我执行此代码时出现异常,我尝试了很多方法来获得解决方案,但没有用,请有人帮助我

android.os.FileUriExposedException: file:///storage/emulated/0/MyRamImages/FILENAME.jpg exposed beyond app through ClipData.Item.getUri()

代码:-

File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages");
imagesFolder.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "FILENAME-"+ n +".jpg";
File image = new File(imagesFolder, fname);
Uri uriSavedImage = Uri.fromFile(image);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(intent, 100);

而不是returnUri.fromFile(mediaFile);

return FileProvider.getUriForFile(MainActivity.this,
                                  BuildConfig.APPLICATION_ID + ".provider",
                                  mediaFile);

这将需要您向 AndroidManifest 添加提供程序:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  ...
  <application
  ...
  <provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
  </provider>
 </application>

然后在res文件夹下的xml文件夹中创建一个provider_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>

参考一次https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en

首先只捕获图像,然后在 onActivityResult 中将图像获取为位图,然后将其保存到您要保存的路径。

private void openCamera()
{
        // Start the camera and take the image
        // handle the storage part in on activity result
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, CAPTURE_IMAGE_REQUEST_CODE);
}

并在activity结果方法里面写下下面的代码。

if (requestCode == CAPTURE_IMAGE_REQUEST_CODE)
{
     if (resultCode == RESULT_OK)
     {
         Bitmap imgBitmap = (Bitmap) data.getExtras().get("data");
         File sd = Environment.getExternalStorageDirectory();
         File imageFolder = new File(sd.getAbsolutePath() + File.separator +
                        "FolderName" + File.separator + "InsideFolderName");

         if (!imageFolder.isDirectory())
         {
              imageFolder.mkdirs();
         }

         File mediaFile = new File(imageFolder + File.separator + "img_" +
                            System.currentTimeMillis() + ".jpg");

         FileOutputStream fileOutputStream = new FileOutputStream(mediaFile);
         imgBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream);
         fileOutputStream.close();
     }
}

这在 7.1.1 和更低版本中也适用于我。