Android 11 保存图片到根目录的实现步骤

为了帮助你更好地理解如何在Android 11上保存图片到根目录,我将分为以下几个步骤来详细解释:

  1. 检查运行时权限
  2. 获取外部存储目录
  3. 创建保存图片的文件
  4. 将图片保存到文件中
  5. 刷新媒体库

下面将逐一说明每个步骤所需的代码和操作。

1. 检查运行时权限

在Android 11及更高版本中,对于访问外部存储的权限需要进行动态申请。首先,我们需要在清单文件(AndroidManifest.xml)中添加以下权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

然后,在代码中我们需要使用以下代码来检查并申请权限:

// 检查是否有存储权限
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {
    // 没有权限,申请权限
    ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
            REQUEST_CODE_PERMISSION);
} else {
    // 已有权限,执行保存图片操作
    saveImageToRootDirectory();
}

2. 获取外部存储目录

在Android 11中,由于对存储权限进行了更严格的限制,我们不能直接使用Environment.getExternalStorageDirectory()方法来获取外部存储目录。取而代之,我们可以使用Context.getExternalFilesDir()方法来获取应用的专属目录,然后在该目录下创建一个新的文件夹用于存储图片。

// 获取应用的外部存储目录
File externalFilesDir = context.getExternalFilesDir(null);
if (externalFilesDir != null) {
    // 创建保存图片的文件夹
    File imageDirectory = new File(externalFilesDir, "Images");
    if (!imageDirectory.exists()) {
        imageDirectory.mkdirs();
    }
    // 创建保存图片的文件
    File imageFile = new File(imageDirectory, "image.png");
}

3. 创建保存图片的文件

在上一步中,我们使用File类来创建保存图片的文件夹和文件。需要注意的是,Android 11要求我们在清单文件中声明requestLegacyExternalStorage属性为true,以便使用旧版的外部存储访问方式。

在清单文件中添加以下属性:

<application
    ...
    android:requestLegacyExternalStorage="true"
    ...>
    ...
</application>

4. 将图片保存到文件中

在保存图片之前,我们需要先获得图片的Bitmap对象。假设你已经有了一个Bitmap对象,接下来,我们可以使用以下代码将其保存到文件中:

try (OutputStream outputStream = new FileOutputStream(imageFile)) {
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
    outputStream.flush();
} catch (IOException e) {
    e.printStackTrace();
}

5. 刷新媒体库

为了让系统能够感知到刚保存的图片,我们需要发送一个媒体库刷新广播。这可以通过以下代码实现:

MediaScannerConnection.scanFile(context, new String[] { imageFile.getAbsolutePath() },
        null, new MediaScannerConnection.OnScanCompletedListener() {
            @Override
            public void onScanCompleted(String path, Uri uri) {
                // 图片已被扫描到媒体库中
            }
        });

完整代码示例

// 检查是否有存储权限
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {
    // 没有权限,申请权限
    ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
            REQUEST_CODE_PERMISSION);
} else {
    // 已有权限,执行保存图片操作
    saveImageToRootDirectory();
}

// 保存图片到根目录
private void saveImageToRootDirectory() {
    // 获取应用的外部存储目录
    File externalFilesDir = context.getExternalFilesDir(null);
    if (externalFilesDir != null) {
        // 创建保存图片的文件夹
        File imageDirectory = new File(externalFilesDir, "Images");
        if (!imageDirectory.exists()) {
            imageDirectory.mkdirs();
        }
        // 创建保存图片的文件
        File imageFile = new File(imageDirectory, "image.png");