【我的安卓第一课】Android 运行时权限

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_STATEWAKE_LOCKACCESS_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版本对权限的分类可能存在差异 ,这可能真的需要多练,多写

Manifest.permission

Android 中的权限

请求特殊权限

请求运行时权限

相关推荐
inmK12 小时前
蓝奏云官方版不好用?蓝云最后一版实测:轻量化 + 不限速(避更新坑) 蓝云、蓝奏云第三方安卓版、蓝云最后一版、蓝奏云无广告管理工具、安卓网盘轻量化 APP
android·工具·网盘工具
giaoho2 小时前
Android 热点开发的相关api总结
android
咖啡の猫3 小时前
Android开发-常用布局
android·gitee
程序员老刘4 小时前
Google突然“变脸“,2026年要给全球开发者上“紧箍咒“?
android·flutter·客户端
Tans54 小时前
Androidx Lifecycle 源码阅读笔记
android·android jetpack·源码阅读
雨白4 小时前
实现双向滑动的 ScalableImageView(下)
android
峥嵘life5 小时前
Android Studio新版本编译release版本apk实现
android·ide·android studio
参宿四南河三7 小时前
Kotlin的Flow用法(实例加长加倍版)
app·响应式编程
studyForMokey7 小时前
【Android 消息机制】Handler
android
敲代码的鱼哇7 小时前
跳转原生系统设置插件 支持安卓/iOS/鸿蒙UTS组件
android·ios·harmonyos