1. 引言
在 Android 早期,各类 APP 可以说是"群魔乱舞"。许多 APP 巴不得自己获得 root 权限,把手机上用户的信息全"拿"走。如 Android 5.1 Lollipop 及更早,应用的权限管理方式采用的是"安装时权限授予 "模式,也就是说,用户在安装应用时需要一次性同意所有应用声明的权限 ,否则就无法安装。这种机制虽然简单直接,但存在明显弊端:用户缺乏对权限的细粒度控制,无法了解每个权限的具体用途,使得有些应用"趁虚而入",过度索取权限。
随着 Android 系统的发展,Google 在 Android 6.0 Marshmallow 中引入了运行时权限 机制。这一变革让用户可以在使用某个功能时动态授权或拒绝特定权限,从而实现更精细、透明的权限控制,大大提升了系统的安全性与用户体验。
下文将是对运行时权限进行的介绍。
2. 运行时权限
运行时权限指的是应用在运行过程中根据需要向用户请求特定权限 的一种机制。它不同于传统的安装时权限模型,而是让用户在实际使用某个功能时决定是否允许该操作。
例如:
- 当用户点击"拍照"按钮时,应用才请求相机权限;
- 当用户点击"定位"按钮时,应用才请求位置权限。
这样既提高了用户的安全意识,也减少了不必要的权限请求,避免用户产生反感。
2.1 权限的分类
Android 将权限分为四大类:
2.1.1 一般权限
这类权限被分配为normal
保护级别,其不会涉及敏感用户数据或系统资源,系统会自动授予这些权限,无需用户手动确认。
例如,常见的普通权限ACCESS_NETWORK_STATE
、WAKE_LOCK
、ACCESS_WIFI_STATE
等,这些权限不会涉及敏感用户数据或系统资源。
2.1.2 签名权限
这类权限被分配为signature
保护级别,只有当应用与定义权限的应用或 OS 使用相同的证书签名时,系统才会向应用授予签名权限。
通常用于一些实现特权服务(如自动填充或 VPN 服务)的应用等。有些签名权限不适合第三方应用使用,只能系统应用使用。
这个权限以后遇到了再说,不过该权限也是满足条件后系统自动授予的
2.1.3 运行时权限

运行时权限也称为危险权限,被定义为dangerous
, 这类权限可能影响用户隐私或设备数据 ,必须由用户主动授权。当应用请求运行时权限时,系统会显示运行时权限提示。在每次使用运行时权限时必须进行if
判断,不得假设已经授权
常见的运行时权限有:
- 存储权限(
READ_MEDIA_IMAGES
,READ_MEDIA_VIDEO
) - 相机权限(
CAMERA
) - 通知权限(
POST_NOTIFICATIONS
)
注意:权限是按组划分的,同一组内的任意权限被授权后,其他权限也会默认获得授权。
2.1.3 特殊权限
系统会为特殊权限分配 appop
保护级别,特殊权限与特定的应用操作相对应。只有平台和原始设备制造商 (OEM) 可以定义特殊权限。
这不是本文重点,具体如何请求特殊权限可见请求特殊权限
用户想要使用特殊权限,只能将页面跳转到系统的特殊权限授予页面。
3. 运行时权限的申请流程

以申请相册权限为例,如下:
3.1 在 AndroidManifest.xml
中声明权限
xml
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
3.3 判断并申请权限
在执行相关操作时,要去申请权限
java
findViewById(R.id.button).setOnClickListener(v -> {
if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES)) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_MEDIA_IMAGES}, 1);
} else {
Log.d(TAG, "Permission already granted");
}
});
3.4 等待用户授权
当申请权限后,手机就会弹出授权要求
3.3 处理用户授权结果
java
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.d(TAG, "onRequestPermissionsResult: " + requestCode + ", " + Arrays.toString(permissions) + ", " + Arrays.toString(grantResults));
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Permission granted");
} else {
Log.d(TAG, "Permission denied");
}
break;
default:
Log.d(TAG, "Unknown request code: " + requestCode);
break;
}
}
成功:
onRequestPermissionsResult: 1, [android.permission.READ_MEDIA_IMAGES], [0]
失败:
onRequestPermissionsResult: 1, [android.permission.READ_MEDIA_IMAGES], [-1]
4. 总结与参考
Android 运行时权限机制的引入,可以说明Android保护用户隐私的重要措施。不过要注意的是, Android的权限系统是比较大的,所以开发者要注意自己用的API,不同的API版本对权限的分类可能存在差异 ,这可能真的需要多练,多写。