捕获的图像未存储在 android 11 中

问题描述

我无法将捕获的图像存储在 (getExternalFilesDir(Environment.DIRECTORY_PICTURES)) android 11 设备中。

我已经添加了 使用权限android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/ 在清单和所有文件访问中。但它不起作用。

            if (!Environment.isExternalStorageManager()) {
                try {
                    val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
                    intent.addCategory("android.intent.category.DEFAULT")
                    intent.data = Uri.parse(String.format("package:%s",applicationContext.packageName))
                    startActivityForResult(intent,2296)
                } catch (e: Exception) {
                    val intent = Intent()
                    intent.action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
                    startActivityForResult(intent,2296)
                }
            }
        }

this code is working below android 11 device. but in android 11 file is not creating

File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
                    .toString() + "/" + FolderName )

解决方法

使用此代码保存捕获的图像

String mPath = Environment.getExternalStorageDirectory() + "/Print";
    Bitmap tmp = BitmapFactory.decodeFile(mPath);

 File imageFile = new File(mPath);


    FileOutputStream outStream;

    try
    {
        outStream = new FileOutputStream(imageFile);

        try
        {
            bitmap.compress(Bitmap.CompressFormat.JPEG,quality,outStream);
            outStream.flush();
            outStream.close();
        } catch (IOException e)
        {
            e.printStackTrace();
        }

    } catch (Exception e)
    {
        e.printStackTrace();
    }
,

由于范围存储问题,您手机的相机无权在指定位置写入。因此,要解决此问题,您需要使用文件提供程序并为其授予适当的权限,以便相机可以将图像写入您的文件。

要做到这一点,

  1. 创建一个 FileProvider。在您的清单文件中,添加:
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />        // <-------- see this
        </provider>

现在在您的 files.xml 文件夹中创建一个 res/xml 文件。在里面,写一些代码:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <cache-path
        name="camera"
        path="Camera/" />
    <cache-path
        name="cache"
        path="/" />
    <files-path
        name="files"
        path="." />
    <external-path
        name="external"
        path="." />
    <external-files-path
        name="my_images"
        path="/"/>
// todo: add necessary folders according to your requirements...
// also,this is an old example. Consider googling for the latest style. I'm just copying from an old project I have,and it kinda works...
</paths>

所以在这里我们为 FileProvider 提供了可以与外部应用程序共享的文件夹。 2. 现在创建一个你想要存储照片的 uri。在您的活动中:

Context applicationContext = getApplicationContext();
File root = getCachedDir(); // consider using getExternalFilesDir(Environment.DIRECTORY_PICTURES); you need to check the file_paths.xml
        File capturedPhoto = new File(root,"some_photo.jpeg");
        if(!photoFile.exists()) {
            photoFile.mkdirs();
        }
        Uri photoURI = FileProvider.getUriForFile(applicationContext,applicationContext.getPackageName() + ".fileprovider",capturedPhoto);

请注意,我的项目需要临时保存图片,所以我使用了cachedDir。如果您永久保存照片,请使用 getExternalFilesDir(Environment.DIRECTORY_PICTURES); 并正确修改 file_paths.xml。

  1. 现在我们有了正确的 uri,我们可以调用相机意图:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoURI);
        startActivityForResult(takePictureIntent,REQUEST_CODE);
  1. 最后,在活动结果中,做一些事情:
    @Override
    public void onActivityResult(int requestCode,int resultCode,Intent data) {
        super.onActivityResult(requestCode,resultCode,data);
  if(requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
    // todo: maybe show photo in an imageView
}
}

我希望这有效。

编辑

如果您在生产环境中使用此应用,那么依赖 android 的默认相机应用是个坏主意。我们的应用程序以前使用过这种方式,并且可以与三星的默认相机配合使用。但是我们的很多用户都使用了第三方应用程序,例如 PixArt,它们不会将照片保存到我们指定的位置。所以我们必须使用 CameraX 实现一个内置相机。因此,请考虑使用 CameraX 或其他一些相机库。