【我的安卓第一课】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 中的权限

请求特殊权限

请求运行时权限

相关推荐
itgather8 分钟前
安卓设备信息查看器 - 源码编译
android
whysqwhw12 分钟前
OkHttp之buildSrc模块分析
android
hsx66614 分钟前
从源码角度理解Android事件的传递流程
android
刺客xs2 小时前
MYSQL数据库----DCL语句
android·数据库·mysql
iReaShare2 小时前
如何将数据从一部手机传输到另一部手机?
android
慢行的骑兵2 小时前
Android音视频探索之旅 | C++层使用OpenGL ES实现视频渲染
android·音视频·ndk
iReaShare3 小时前
将CSV联系人导入安卓手机的3种简单方法
android
whysqwhw5 小时前
Okttp之unixdomainsockets模块分析
android
非凡ghost5 小时前
Android System WebView:Android生态的核心组件
android