在 Android 中申请相册的读写权限涉及到外部存储权限的管理。从 Android 6.0 (API 级别 23) 开始,应用必须在运行时请求危险权限。对于 Android 11 (API 级别 30) 及以上版本,外部存储的权限管理变得更加严格,引入了分区存储模型(Scoped Storage)来限制应用对其他应用文件的访问。

基本步骤:

1.在 AndroidManifest.xml 文件中声明权限:

   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
   
  • 1.
  • 2.
  • 3.

2.检查权限是否已被授予:

使用 ContextCompat.checkSelfPermission() 方法检查权限状态。

3.请求权限:

如果权限未被授予,使用 ActivityCompat.requestPermissions() 请求权限。

4.处理权限请求的结果:

实现 onRequestPermissionsResult() 方法以处理用户的响应。

示例代码:

MainActivity.java 中实现:

import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    private static final int PERMISSIONS_REQUEST = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 检查权限是否已经授予
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            // 如果没有被授予,请求权限
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    PERMISSIONS_REQUEST);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == PERMISSIONS_REQUEST) {
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                // 权限被用户接受
            } else {
                // 权限被用户拒绝
            }
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.

注意事项:

  • 对于 Android 11 及以上版本,建议使用 Environment.DIRECTORY_PICTURESEnvironment.DIRECTORY_DOWNLOADS 这样的公共目录来保存文件,而不是直接写入外部存储根目录。
  • 如果应用的目标 SDK 版本是 Android 11 (API 级别 30) 或更高版本,通常不需要显式请求 WRITE_EXTERNAL_STORAGE READ_EXTERNAL_STORAGE 权限,而是使用更细粒度的权限如 MANAGE_EXTERNAL_STORAGE 或者使用存储访问框架 (Storage Access Framework)。

实例代码

步骤 1: 在 AndroidManifest.xml 文件中声明权限

首先,在您的项目的 AndroidManifest.xml 文件中添加以下权限声明:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.permissionexample">

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

    <application
        ...
        <activity
            android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

 步骤 2: 在 MainActivity.java 中实现权限请求逻辑

接下来,在 MainActivity.java 文件中实现权限请求逻辑:

import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    private static final int PERMISSIONS_REQUEST = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 检查权限是否已经授予
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            // 如果没有被授予,请求权限
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    PERMISSIONS_REQUEST);
        } else {
            // 权限已授予,可以执行相关操作
            onPermissionsGranted();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == PERMISSIONS_REQUEST) {
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                // 权限被用户接受
                onPermissionsGranted();
            } else {
                // 权限被用户拒绝
                onPermissionsDenied();
            }
        }
    }

    private void onPermissionsGranted() {
        // 权限被授予后执行的操作
        // 例如打开相册或进行文件读写操作
    }

    private void onPermissionsDenied() {
        // 权限被拒绝后执行的操作
        // 提示用户权限的重要性或者提供其他操作方式
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.

解释

权限请求:
  • 在 onCreate 方法中检查权限是否已经被授予。
  • 如果权限未被授予,则调用 requestPermissions 方法来请求权限。
处理权限请求结果:
  • 在 onRequestPermissionsResult 方法中处理权限请求的结果。
  • 根据用户的选择,调用相应的回调方法。
权限被授予后的操作:
  • 当权限被授予后,可以在 onPermissionsGranted 方法中执行需要这些权限的操作。
权限被拒绝后的操作:
  • 当权限被拒绝后,可以在 onPermissionsDenied 方法中提示用户或提供其他操作方式。
注意事项
  • 确保您的应用遵循最新的 Android 安全指南和最佳实践。
  • 对于 Android 11 (API 级别 30) 及以上版本,建议使用更细粒度的权限,如 MANAGE_EXTERNAL_STORAGE 或者使用存储访问框架 (Storage Access Framework)。

通过上述示例代码,您可以实现基本的相册读写权限请求功能。