在 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"/>
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 {
// 权限被用户拒绝
}
}
}
}
注意事项:
- 对于 Android 11 及以上版本,建议使用
Environment.DIRECTORY_PICTURES
或Environment.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>
步骤 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() {
// 权限被拒绝后执行的操作
// 提示用户权限的重要性或者提供其他操作方式
}
}
解释
权限请求:
- 在 onCreate 方法中检查权限是否已经被授予。
- 如果权限未被授予,则调用 requestPermissions 方法来请求权限。
处理权限请求结果:
- 在 onRequestPermissionsResult 方法中处理权限请求的结果。
- 根据用户的选择,调用相应的回调方法。
权限被授予后的操作:
- 当权限被授予后,可以在 onPermissionsGranted 方法中执行需要这些权限的操作。
权限被拒绝后的操作:
- 当权限被拒绝后,可以在 onPermissionsDenied 方法中提示用户或提供其他操作方式。
注意事项
- 确保您的应用遵循最新的 Android 安全指南和最佳实践。
- 对于 Android 11 (API 级别 30) 及以上版本,建议使用更细粒度的权限,如 MANAGE_EXTERNAL_STORAGE 或者使用存储访问框架 (Storage Access Framework)。
通过上述示例代码,您可以实现基本的相册读写权限请求功能。