Android 11 中读取相册的实现指南

在 Android 11 及以上版本中,Google 提出了 Scoped Storage,这意味着访问设备存储的方式发生了变化。特别是在读取媒体文件(如相册中的照片)时,开发者需要遵循新的权限和 API 机制。本文将逐步指导你如何使用 MediaStore API 来实现这一功能。

流程概述

以下表格展示了实现 MediaStore 读取相册的流程:

步骤 描述
1 添加必要的权限
2 请求运行时权限
3 使用 MediaStore 查询相册图片
4 处理获取到的图片数据

步骤详解

1. 添加必要的权限

首先,你需要在 AndroidManifest.xml 文件中声明所需的权限:

<manifest xmlns:android="
    package="com.example.yourapp">
    
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
    <application
        ... >
        ...
    </application>
</manifest>

注释:上述代码为应用声明了读取外部存储的权限。

2. 请求运行时权限

在 Android 6.0 及以上版本,用户需要授权应用权限。以下是请求运行时权限的代码示例:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) 
        != PackageManager.PERMISSION_GRANTED) {
    
    // 权限未被授予,请求权限
    ActivityCompat.requestPermissions(this, 
            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
            1);
} else {
    // 权限已被授予,可以读取相册
    readGalleryImages();
}

注释:检查是否已获得权限,如果没有,则请求权限;否则,调用读取图片的方法。

3. 使用 MediaStore 查询相册图片

在用户授予权限后,可以使用 MediaStore API 获取相册中的图片:

private void readGalleryImages() {
    Uri collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    String[] projection = new String[]{
            MediaStore.Images.Media._ID,
            MediaStore.Images.Media.DISPLAY_NAME
    };
    
    Cursor cursor = getContentResolver().query(
            collection,
            projection,
            null,
            null,
            null
    );

    if (cursor != null) {
        int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
        int nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);

        while (cursor.moveToNext()) {
            long id = cursor.getLong(idColumn);
            String name = cursor.getString(nameColumn);

            // 图片的 Uri
            Uri contentUri = ContentUris.withAppendedId(collection, id);
            Log.d("Gallery Image", "Name: " + name + ", Uri: " + contentUri);
        }
        cursor.close();
    }
}

注释:上述代码查询了设备中的所有图片,提取了每张图片的 ID 和名称,并生成了其 Uri,方便后续使用。

4. 处理获取到的图片数据

获取到图片的 Uri 后,你可以使用它来加载图片。例如,利用 Glide 加载图片:

Glide.with(this)
    .load(contentUri)
    .into(imageView);

注释:使用 Glide 加载图片,imageView 是界面中展示图片的控件。

状态图

下面是应用状态图,用于展示不同状态之间的转移:

stateDiagram
    [*] --> CheckPermission
    CheckPermission --> PermissionGranted : granted
    CheckPermission --> PermissionDenied : denied
    PermissionDenied --> CheckPermission : recheck
    PermissionGranted --> ReadGallery : start reading
    ReadGallery --> [*]

关系图

以下是与 MediaStore 相关的对象关系图:

erDiagram
    IMAGE {
        int id
        string displayName
        string uri
    }
    USER {
        int id
        string name
    }
    IMAGE ||--o{ USER : accesses

结尾

在本指南中,我们讲解了如何在 Android 11 中使用 MediaStore 读取相册图片。我们强调了新的权限管理策略,以及如何通过 MediaStore API 读取和处理图片。希望这篇文章能够帮助你更好地理解和实现相册读取功能。随着技术的发展,保持对新变化的了解是非常重要的,继续探索和实践,相信你会在 Android 开发的道路上越走越远!