Skip to content

Android 权限系统深度解析

目录

  1. 权限系统概述
  2. 权限级别详解
  3. 运行时权限 (Android 6.0+)
  4. 权限组(Permission Groups)
  5. 权限拒绝处理
  6. 特殊权限
  7. 权限自动授予
  8. 权限检查最佳实践
  9. Android 版本权限变化
  10. 面试考点

1. 权限系统概述

1.1 权限系统架构

Android 权限系统架构:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   应用层                                                    │
│   ├─ 声明权限(AndroidManifest.xml)                        │
│   ├─ 请求权限(运行时)                                      │
│   └─ 检查权限(代码中)                                      │
│          ↓                                                  │
│   框架层                                                    │
│   ├─ PackageManagerService 管理权限                          │
│   ├─ ActivityManagerService 处理权限请求                     │
│   └─ PermissionController 控制权限                           │
│          ↓                                                  │
│   系统层                                                    │
│   ├─ SELinux 强制访问控制                                    │
│   ├─ 沙箱隔离                                                │
│   └─ 内核权限检查                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

1.2 权限发展历程

Android 权限系统演进:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   Android 5.1 及之前                                        │
│   ├─ 安装时授权                                              │
│   ├─ 全有或全无                                              │
│   ├─ 用户无法选择权限                                        │
│   └─ 权限一次性授予                                          │
│                                                             │
│   Android 6.0 (M)                                           │
│   ├─ 运行时权限引入                                          │
│   ├─ 危险权限需要运行时请求                                   │
│   ├─ 用户可选择性授权                                        │
│   └─ 权限可动态撤销                                          │
│                                                             │
│   Android 7.0 (N)                                           │
│   ├─ 权限组优化                                              │
│   ├─ 权限请求优化                                            │
│   └─ 后台权限限制开始                                        │
│                                                             │
│   Android 8.0 (O)                                           │
│   ├─ 后台启动限制                                            │
│   ├─ 精确位置权限                                            │
│   └─ 通知权限细化                                            │
│                                                             │
│   Android 9.0 (Pie)                                         │
│   ├─ 分区增强                                                │
│   ├─ 后台位置限制                                            │
│   └─ 权限使用限制                                            │
│                                                             │
│   Android 10 (Q)                                            │
│   ├─ 模糊位置权限                                            │
│   ├─ 后台权限限制加强                                        │
│   ├─ 分区存储                                                │
│   └─ 权限自动授予优化                                        │
│                                                             │
│   Android 11 (R)                                            │
│   ├─ 一次性权限                                              │
│   ├─ 后台权限限制进一步                                      │
│   ├─ 权限使用情况显示                                        │
│   └─ 通知权限分类                                            │
│                                                             │
│   Android 12 (S)                                            │
│   ├─ 通知权限强制请求                                        │
│   ├─ 权限请求优化                                            │
│   ├─ 权限使用情况报告                                        │
│   └─ 后台权限限制更严格                                      │
│                                                             │
│   Android 13 (T)                                            │
│   ├─ 媒体权限拆分                                            │
│   ├─ 通知权限正式引入                                        │
│   ├─ 短信权限细化                                            │
│   └─ 通话权限细化                                            │
│                                                             │
│   Android 14 (U)                                            │
│   ├─ 权限请求优化                                            │
│   ├─ 权限使用追踪                                            │
│   ├─ 权限管理改进                                            │
│   └─ 隐私权限增强                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2. 权限级别详解

2.1 普通权限 (Normal)

普通权限特点:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   特点                                                      │
│   ├─ 不影响用户隐私                                         │
│   ├─ 安装时自动授予                                         │
│   ├─ 不需要用户确认                                         │
│   └─ 不需要运行时请求                                        │
│                                                             │
│   示例权限                                                  │
│   ├─ INTERNET         # 网络访问                           │
│   ├─ ACCESS_NETWORK_STATE  # 网络状态                      │
│   ├─ VIBRATE          # 振动                               │
│   ├─ WRITE_SETTINGS   # 写入设置 (实际是 signature)        │
│   ├─ RECEIVE_BOOT_COMPLETED # 开机广播                     │
│   ├─ FOREGROUND_SERVICE # 前台服务                          │
│   └─ POST_NOTIFICATIONS # 发送通知 (Android 13+ 需请求)    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2.2 危险权限 (Dangerous)

危险权限分类:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   相机权限                                                  │
│   ├─ CAMERA           # 访问相机                           │
│   └─ 涉及用户隐私,需要运行时请求                            │
│                                                             │
│   位置权限                                                  │
│   ├─ ACCESS_FINE_LOCATION   # 精确位置                      │
│   ├─ ACCESS_COARSE_LOCATION # 模糊位置                      │
│   └─ 涉及用户位置隐私                                        │
│                                                             │
│   通讯录权限                                                │
│   ├─ READ_CONTACTS      # 读取通讯录                        │
│   ├─ WRITE_CONTACTS     # 写入通讯录                        │
│   └─ 涉及用户联系人隐私                                      │
│                                                             │
│   日历权限                                                  │
│   ├─ READ_CALENDAR      # 读取日历                          │
│   ├─ WRITE_CALENDAR     # 写入日历                          │
│   └─ 涉及用户日程隐私                                        │
│                                                             │
│   电话权限                                                  │
│   ├─ CALL_PHONE         # 拨打电话                          │
│   ├─ READ_PHONE_STATE   # 读取电话状态                      │
│   ├─ READ_PHONE_NUMBERS # 读取电话号码                      │
│   ├─ READ_CALL_LOG      # 读取通话记录                      │
│   ├─ WRITE_CALL_LOG     # 写入通话记录                      │
│   └─ 涉及用户通话隐私                                        │
│                                                             │
│   短信权限                                                  │
│   ├─ SEND_SMS           # 发送短信                          │
│   ├─ RECEIVE_SMS        # 接收短信                          │
│   ├─ READ_SMS           # 读取短信                          │
│   └─ 涉及用户短信隐私                                        │
│                                                             │
│   存储权限                                                  │
│   ├─ READ_EXTERNAL_STORAGE   # 读取外部存储                 │
│   ├─ WRITE_EXTERNAL_STORAGE  # 写入外部存储                 │
│   ├─ MANAGE_EXTERNAL_STORAGE # 管理所有文件 (Android 11+)   │
│   └─ 涉及用户文件隐私                                        │
│                                                             │
│   传感器权限                                                │
│   ├─ BODY_SENSORS     # 身体传感器                          │
│   └─ 涉及用户健康数据                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2.3 签名权限 (Signature)

签名权限特点:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   特点                                                      │
│   ├─ 仅限系统签名应用                                       │
│   ├─ 安装时自动授予(如果签名匹配)                          │
│   ├─ 普通应用无法获得                                       │
│   └─ 用于系统级功能                                         │
│                                                             │
│   示例权限                                                  │
│   ├─ REBOOT            # 重启系统                           │
│   ├─ SET_DEBUG_APP     # 设置调试应用                        │
│   ├─ BIND_ACCESSIBILITY_SERVICE # 绑定无障碍服务             │
│   ├─ BIND_INPUT_METHOD  # 绑定输入法                         │
│   ├─ WRITE_SETTINGS    # 写入系统设置                        │
│   ├─ DELETE_PACKAGES   # 删除应用                           │
│   └─ GRANT_PERMISSIONS # 授予权限                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2.4 签名或系统权限 (Signature or System)

签名或系统权限:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   特点                                                      │
│   ├─ 系统应用或签名应用可获得                                │
│   ├─ 系统分区应用自动授予                                    │
│   ├─ 普通应用无法获得                                       │
│   └─ 用于系统级功能                                         │
│                                                             │
│   示例权限                                                  │
│   ├─ BIND_TELEphony_SERVICE   # 绑定电话服务                │
│   ├─ BROADCAST_STICKY         # 发送粘性广播                │
│   ├─ PROCESS_OUTGOING_CALLS   # 处理拨出通话                │
│   └─ READ_LOGS                # 读取日志                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

3. 运行时权限 (Android 6.0+)

3.1 运行时权限请求流程

运行时权限请求流程:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   应用检查权限状态                                          │
│          ↓                                                  │
│   ┌─────────────────────────────────────────────────┐       │
│   │ 检查是否已授予                                │       │
│   │ - ContextCompat.checkSelfPermission()          │       │
│   └─────────────────────────────────────────────────┘       │
│          ↓                                                  │
│   未授予则请求权限                                          │
│          ↓                                                  │
│   ┌─────────────────────────────────────────────────┐       │
│   │  Activity.requestPermissions()                  │       │
│   │  - 显示系统权限对话框                             │       │
│   │  - 用户选择允许或拒绝                             │       │
│   └──────────────────────────────────────────┘       │
│          ↓                                                  │
│   用户做出选择                                              │
│          ↓                                                  │
│   ┌──────────────────────────────────────────┐       │
│   │ 回调 onRequestPermissionsResult()          │       │
│   │  - 处理允许结果                             │       │
│   │  - 处理拒绝结果                             │       │
│   └──────────────────────────────────────────┘       │
│          ↓                                                  │
│   执行相应操作                                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

3.2 运行时权限请求代码

基本权限请求:

java
// 运行时权限请求

public class PermissionActivity extends AppCompatActivity {
    
    private static final int PERMISSION_REQUEST_CODE = 100;
    
    // 请求相机权限
    public void requestCameraPermission() {
        // 1. 检查权限
        if (ContextCompat.checkSelfPermission(this, 
                Manifest.permission.CAMERA) 
                != PackageManager.PERMISSION_GRANTED) {
            
            // 2. 检查是否需要说明
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.CAMERA)) {
                // 显示说明对话框
                showPermissionRationaleDialog();
            }
            
            // 3. 请求权限
            ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.CAMERA},
                PERMISSION_REQUEST_CODE);
        } else {
            // 权限已授予,执行操作
            useCamera();
        }
    }
    
    // 处理权限结果
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                          @NonNull String[] permissions,
                                          @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && 
                grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 权限已授予
                useCamera();
            } else {
                // 权限被拒绝
                showPermissionDeniedDialog();
            }
        }
    }
}

3.3 多权限请求

请求多个权限:

java
// 请求多个权限

public void requestMultiplePermissions() {
    // 1. 检查需要请求的权限
    List<String> permissionsToRequest = new ArrayList<>();
    
    if (ContextCompat.checkSelfPermission(this, 
            Manifest.permission.CAMERA) 
            != PackageManager.PERMISSION_GRANTED) {
        permissionsToRequest.add(Manifest.permission.CAMERA);
    }
    
    if (ContextCompat.checkSelfPermission(this, 
            Manifest.permission.RECORD_AUDIO) 
            != PackageManager.PERMISSION_GRANTED) {
        permissionsToRequest.add(Manifest.permission.RECORD_AUDIO);
    }
    
    if (ContextCompat.checkSelfPermission(this, 
            Manifest.permission.WRITE_EXTERNAL_STORAGE) 
            != PackageManager.PERMISSION_GRANTED) {
        permissionsToRequest.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }
    
    // 2. 如果有需要请求的权限
    if (!permissionsToRequest.isEmpty()) {
        ActivityCompat.requestPermissions(this,
            permissionsToRequest.toArray(new String[0]),
            PERMISSION_REQUEST_CODE);
    } else {
        // 所有权限都已授予
        usePermissions();
    }
}

// 处理多权限结果
@Override
public void onRequestPermissionsResult(int requestCode,
                                      @NonNull String[] permissions,
                                      @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
    if (requestCode == PERMISSION_REQUEST_CODE) {
        boolean allGranted = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                allGranted = false;
                break;
            }
        }
        
        if (allGranted) {
            usePermissions();
        } else {
            showPartialPermissionDeniedDialog();
        }
    }
}

4. 权限组(Permission Groups)

4.1 权限组分类

权限组分类:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   相机组 (CAMERA)                                            │
│   └─ CAMERA                                                │
│                                                             │
│   位置组 (LOCATION)                                         │
│   ├─ ACCESS_FINE_LOCATION                                   │
│   └─ ACCESS_COARSE_LOCATION                                 │
│                                                             │
│   通讯录组 (CONTACTS)                                       │
│   ├─ READ_CONTACTS                                         │
│   └─ WRITE_CONTACTS                                        │
│                                                             │
│   日历组 (CALENDAR)                                         │
│   ├─ READ_CALENDAR                                         │
│   └─ WRITE_CALENDAR                                        │
│                                                             │
│   短信组 (SMS)                                              │
│   ├─ SEND_SMS                                              │
│   ├─ RECEIVE_SMS                                           │
│   └─ READ_SMS                                              │
│                                                             │
│   电话组 (PHONE)                                            │
│   ├─ CALL_PHONE                                            │
│   ├─ READ_PHONE_STATE                                      │
│   ├─ READ_PHONE_NUMBERS                                    │
│   ├─ READ_CALL_LOG                                         │
│   └─ WRITE_CALL_LOG                                        │
│                                                             │
│   存储组 (STORAGE)                                          │
│   ├─ READ_EXTERNAL_STORAGE                                 │
│   └─ WRITE_EXTERNAL_STORAGE                                │
│                                                             │
│   传感器组 (SENSORS)                                        │
│   └─ BODY_SENSORS                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

4.2 权限组优势

权限组优势:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   1. 一次性授予组内所有权限                                 │
│      ├─ 减少权限请求次数                                    │
│      ├─ 提升用户体验                                       │
│      └─ 简化权限管理                                        │
│                                                             │
│   2. 权限关联                                                │
│      ├─ 组内权限相关功能                                    │
│      ├─ 统一管理                                           │
│      └─ 便于用户理解                                        │
│                                                             │
│   3. 权限撤销                                                │
│      ├─ 撤销组权限影响所有                                  │
│      ├─ 统一处理                                           │
│      └─ 便于权限状态同步                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

5. 权限拒绝处理

5.1 权限拒绝类型

权限拒绝类型:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   普通拒绝                                                  │
│   ├─ 用户选择"不允许"                                       │
│   ├─ 可以再次请求                                           │
│   ├─ 显示说明对话框                                         │
│   └─ 建议解释权限用途                                        │
│                                                             │
│   永久拒绝                                                  │
│   ├─ 用户选择"不允许"并勾选"不再询问"                        │
│   ├─ 无法再次自动请求                                       │
│   ├─ 需跳转到设置页面                                       │
│   └─ 用户手动开启权限                                        │
│                                                             │
│   系统拒绝                                                  │
│   ├─ 系统限制(如儿童模式)                                  │
│   ├─ 企业管理器限制                                        │
│   ├─ 安全软件拦截                                           │
│   └─ 需要解除限制                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

5.2 权限拒绝处理策略

处理权限拒绝:

java
// 处理权限拒绝

public class PermissionHandler {
    
    // 检查是否需要说明
    public boolean shouldShowRationale(Activity activity, String permission) {
        return ActivityCompat.shouldShowRequestPermissionRationale(
            activity, permission);
    }
    
    // 检查是否永久拒绝
    public boolean isPermissionPermanentlyDenied(Activity activity, String permission) {
        return !ActivityCompat.shouldShowRequestPermissionRationale(
            activity, permission);
    }
    
    // 跳转到设置页面
    public void openAppSettings(Activity activity) {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
        intent.setData(uri);
        activity.startActivity(intent);
    }
    
    // 显示权限说明对话框
    public void showPermissionRationaleDialog(DialogFragment dialog) {
        dialog.show(getSupportFragmentManager(), "PermissionRationale");
    }
    
    // 处理权限结果
    public void handlePermissionResult(int requestCode, int[] grantResults) {
        if (grantResults.length > 0) {
            for (int result : grantResults) {
                if (result == PackageManager.PERMISSION_GRANTED) {
                    // 权限已授予
                    usePermission();
                } else {
                    // 权限被拒绝
                    handlePermissionDenied();
                }
            }
        }
    }
}

6. 特殊权限

6.1 悬浮窗权限

SYSTEM_ALERT_WINDOW 权限:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   用途                                                      │
│   ├─ 显示在其他应用之上                                     │
│   ├─ 创建悬浮窗                                             │
│   ├─ 画屏取词                                               │
│   └─ 通知提醒                                               │
│                                                             │
│   请求方式                                                  │
│   ├─ 不能通过代码请求                                       │
│   ├─ 需跳转到设置页面                                       │
│   ├─ 用户手动开启                                           │
│   └─ Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)      │
│                                                             │
│   检查权限                                                  │
│   ├─ Settings.canDrawOverlays()                             │
│   └─ 返回 boolean 值                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

请求悬浮窗权限:

java
// 请求悬浮窗权限

public void requestOverlayPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.canDrawOverlays(this)) {
            // 跳转到设置页面
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivity(intent);
        } else {
            // 权限已授予
            createOverlay();
        }
    }
}

6.2 修改系统设置权限

WRITE_SETTINGS 权限:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   用途                                                      │
│   ├─ 修改系统设置                                           │
│   ├─ 修改辅助功能设置                                       │
│   ├─ 修改显示设置                                           │
│   └─ 修改网络设置                                           │
│                                                             │
│   请求方式                                                  │
│   ├─ 不能通过代码请求                                       │
│   ├─ 需跳转到设置页面                                       │
│   ├─ 用户手动开启                                           │
│   └─ Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)          │
│                                                             │
│   检查权限                                                  │
│   ├─ Settings.System.canWrite()                             │
│   └─ 返回 boolean 值                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

请求修改系统设置权限:

java
// 请求修改系统设置权限

public void requestWriteSettingsPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.System.canWrite(this)) {
            // 跳转到设置页面
            Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivity(intent);
        } else {
            // 权限已授予
            modifySettings();
        }
    }
}

6.3 无障碍服务权限

BIND_ACCESSIBILITY_SERVICE 权限:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   用途                                                      │
│   ├─ 无障碍辅助                                             │
│   ├─ 自动点击                                               │
│   ├─ 屏幕读取                                               │
│   ├─ 模拟触摸                                               │
│   └─ 应用自动化                                             │
│                                                             │
│   请求方式                                                  │
│   ├─ 需实现 AccessibilityService                           │
│   ├─ 在 AndroidManifest.xml 声明                             │
│   ├─ 跳转到无障碍设置页面                                    │
│   ├─ 用户手动开启                                           │
│   └─ Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)         │
│                                                             │
│   检查权限                                                  │
│   ├─ AccessibilityManager.isAccessibilityEnabled()          │
│   └─ 返回 boolean 值                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

7. 权限自动授予

7.1 权限自动授予机制

权限自动授予:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   自动授予条件                                              │
│   ├─ 应用来自可信来源                                       │
│   ├─ 应用是系统应用                                         │
│   ├─ 应用是 Google Play 应用                                 │
│   ├─ 权限是普通权限                                         │
│   └─ 用户之前授予过同类权限                                  │
│                                                             │
│   不自动授予情况                                            │
│   ├─ 危险权限需要明确请求                                    │
│   ├─ 特殊权限需要手动设置                                    │
│   ├─ 用户明确拒绝过                                          │
│   └─ 应用来自非可信来源                                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

7.2 优化权限请求

权限请求优化:

java
// 权限请求优化

public class PermissionOptimizer {
    
    // 按需请求权限
    public void requestPermissionOnDemand(String permission) {
        // 1. 检查功能是否需要
        if (isFeatureNeeded(permission)) {
            // 2. 在用户使用功能时请求
            requestPermissionAtFeatureUse(permission);
        }
    }
    
    // 分步请求权限
    public void requestPermissionsStepByStep() {
        // 1. 先请求核心功能权限
        requestCorePermissions();
        
        // 2. 用户使用时再请求其他权限
        requestAdditionalPermissionsOnUse();
    }
    
    // 解释权限用途
    public void explainPermissionUsage(String permission) {
        // 1. 显示说明对话框
        showPermissionExplanation(permission);
        
        // 2. 解释权限用途
        explainWhyNeeded(permission);
        
        // 3. 展示隐私政策
        showPrivacyPolicy();
    }
}

8. 权限检查最佳实践

8.1 权限检查清单

权限检查最佳实践:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   1. 最小权限原则                                            │
│      ├─ 只申请必要的权限                                     │
│      ├─ 避免过度申请                                         │
│      └─ 按功能模块申请                                        │
│                                                             │
│   2. 合理时机请求                                            │
│      ├─ 在需要时请求                                         │
│      ├─ 避免启动时批量请求                                    │
│      ├─ 提供功能降级方案                                      │
│      └─ 给予用户选择空间                                      │
│                                                             │
│   3. 友好的权限说明                                          │
│      ├─ 清晰解释权限用途                                      │
│      ├─ 说明为什么需要                                        │
│      ├─ 展示隐私政策                                          │
│      └─ 提供拒绝后的替代方案                                  │
│                                                             │
│   4. 优雅的错误处理                                          │
│      ├─ 处理权限拒绝                                         │
│      ├─ 提供功能降级                                         │
│      ├─ 引导用户设置权限                                      │
│      └─ 避免频繁骚扰                                          │
│                                                             │
│   5. 权限状态同步                                            │
│      ├─ 监听权限变化                                         │
│      ├─ 更新 UI 状态                                           │
│      ├─ 同步权限数据                                          │
│      └─ 处理权限撤销                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

9. Android 版本权限变化

9.1 主要版本变化

Android 版本权限变化:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   Android 6.0 (M)                                           │
│   ├─ 引入运行时权限                                          │
│   ├─ 危险权限需要运行时请求                                   │
│   └─ 权限可动态撤销                                          │
│                                                             │
│   Android 7.0 (N)                                           │
│   ├─ 权限组优化                                              │
│   ├─ 后台权限限制开始                                        │
│   └─ 通知权限细化                                            │
│                                                             │
│   Android 8.0 (O)                                           │
│   ├─ 后台启动限制                                            │
│   ├─ 精确位置权限                                            │
│   └─ Doze 模式加强                                           │
│                                                             │
│   Android 9.0 (Pie)                                         │
│   ├─ 后台位置限制                                            │
│   ├─ 分区存储开始                                            │
│   └─ 权限使用限制                                            │
│                                                             │
│   Android 10 (Q)                                            │
│   ├─ 模糊位置权限                                            │
│   ├─ 分区存储正式推出                                        │
│   ├─ 后台权限限制加强                                        │
│   └─ 一次权限授权                                            │
│                                                             │
│   Android 11 (R)                                            │
│   ├─ 一次性权限                                              │
│   ├─ 通知权限分类                                            │
│   ├─ 权限使用情况显示                                        │
│   └─ 后台权限限制进一步                                      │
│                                                             │
│   Android 12 (S)                                            │
│   ├─ 通知权限强制请求                                        │
│   ├─ 屏幕录制权限                                            │
│   ├─ 麦克风/相机指示器                                       │
│   └─ 权限请求优化                                            │
│                                                             │
│   Android 13 (T)                                            │
│   ├─ 媒体权限拆分                                            │
│   ├─ 通知权限正式引入                                        │
│   ├─ 短信权限细化                                            │
│   ├─ 通话权限细化                                            │
│   └─ 近场通信权限                                            │
│                                                             │
│   Android 14 (U)                                            │
│   ├─ 权限使用追踪                                            │
│   ├─ 权限管理改进                                            │
│   ├─ 隐私权限增强                                            │
│   └─ 应用锁权限                                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

9.2 版本适配代码

版本适配权限:

java
// 版本适配权限

public class VersionAdaptedPermission {
    
    // 请求存储权限
    public void requestStoragePermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11+ 使用分区存储
            requestScopedStorage();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // Android 6.0-10 使用运行时权限
            requestRuntimeStoragePermission();
        } else {
            // Android 5.1 及以下安装时授权
            useStorage();
        }
    }
    
    // 请求位置权限
    public void requestLocationPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // Android 10+ 区分精确/模糊位置
            requestApproximateLocationPermission();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // Android 6.0-9 运行时权限
            requestRuntimeLocationPermission();
        } else {
            // Android 5.1 及以下安装时授权
            useLocation();
        }
    }
    
    // 请求通知权限
    public void requestNotificationPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Android 13+ 需要 POST_NOTIFICATIONS 权限
            requestPostNotificationsPermission();
        } else {
            // Android 12 及以下不需要
            showNotification();
        }
    }
}

10. 面试考点

10.1 基础考点

1. 权限级别分类?

答案:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   权限级别                                                  │
│   ├─ 普通权限 (Normal)       安装时自动授予                  │
│   ├─ 危险权限 (Dangerous)     运行时请求                     │
│   ├─ 签名权限 (Signature)     系统签名应用                   │
│   └─ 签名或系统权限         系统应用                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2. 运行时权限请求流程?

答案:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   运行时权限请求流程                                        │
│   ├─ 检查权限状态                                           │
│   ├─ 检查是否需要说明                                       │
│   ├─ 请求权限                                               │
│   ├─ 用户选择允许或拒绝                                     │
│   └─ 回调处理结果                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

10.2 进阶考点

1. 特殊权限有哪些?

答案:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   特殊权限                                                  │
│   ├─ SYSTEM_ALERT_WINDOW    悬浮窗                          │
│   ├─ WRITE_SETTINGS         修改系统设置                     │
│   ├─ BIND_ACCESSIBILITY_SERVICE  无障碍服务                  │
│   ├─ BIND_VPN_SERVICE       VPN 服务                         │
│   ├─ BIND_WALLPAPER         壁纸服务                         │
│   └─ POST_NOTIFICATIONS     发送通知 (Android 13+)            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2. 权限拒绝如何处理?

答案:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   权限拒绝处理                                              │
│   ├─ 普通拒绝:可以再次请求                                 │
│   ├─ 永久拒绝:跳转到设置页面                                │
│   ├─ 提供功能降级方案                                       │
│   ├─ 解释权限用途                                           │
│   └─ 避免频繁骚扰                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

10.3 高级考点

1. Android 13+ 新增权限?

答案:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   Android 13+ 新增权限                                      │
│   ├─ POST_NOTIFICATIONS     发送通知                        │
│   ├─ READ_MEDIA_IMAGES      读取图片                        │
│   ├─ READ_MEDIA_VIDEO       读取视频                        │
│   ├─ READ_MEDIA_AUDIO       读取音频                        │
│   ├─ READ_CALL_LOG          读取通话记录                      │
│   ├─ READ_SMS               读取短信                        │
│   └─ SEND_SMS/RECEIVE_SMS    发送/接收短信                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2. 权限请求最佳实践?

答案:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   权限请求最佳实践                                          │
│   ├─ 最小权限原则                                          │
│   ├─ 合理时机请求                                          │
│   ├─ 友好的权限说明                                          │
│   ├─ 优雅的错误处理                                          │
│   └─ 权限状态同步                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

文档信息:

  • 字数:约 14000 字
  • 包含:权限级别、运行时权限、权限组、权限拒绝处理、特殊权限、权限自动授予、最佳实践、Android 版本变化、面试考点
  • 代码示例:包含完整的权限请求、检查、处理代码
  • ASCII 流程图:包含多个流程时序图和架构图
  • 最佳实践:权限请求最佳实践、版本适配建议

建议:

  1. 掌握运行时权限请求的完整流程
  2. 了解各 Android 版本的权限变化
  3. 熟悉特殊权限的请求方式
  4. 学习权限请求的最佳实践