一、前言

现代移动 OS 权限已经从 “安装授权” 进化为:
细粒度授权 + 临时授权 + 数据级授权 + 跨设备可信授权

Android、iOS、HarmonyOS 三者在底层架构、权限模型、API 设计、安全机制上差异极大。
本文从架构 → 权限模型 → 完整代码 → 界面截图描述 → 风险点 → 最佳实践全链路对比。


二、底层架构与权限核心服务对比

2.1 核心架构一览

系统 内核 权限核心服务 沙箱机制 权限管控特点
Android Linux 宏内核 PackageManagerService、AMS、SELinux UID 隔离 + SELinux 开放、厂商可定制、碎片化
iOS Darwin XNU TCC 服务、Security 框架 强容器沙箱 统一严格、无定制、闭源
HarmonyOS 自研微内核 AbilityAccessCtrl、TokenID 鉴权 安全沙箱 + 加密数据区 数据级授权、分布式、自动回收

2.2 权限流程简图(文字版截图描述)

Android 权限流程截图描述

在这里插入图片描述

iOS TCC 权限流程截图描述

在这里插入图片描述

HarmonyOS 权限架构截图描述

在这里插入图片描述


三、权限模型与授权弹窗样式详解

3.1 Android 授权弹窗

Android 危险权限弹窗样式:

┌─────────────────────────┐
│  获取设备位置信息?      │
│  允许 | 拒绝            │
│ ☑ 拒绝后不再询问         │
└─────────────────────────┘

在这里插入图片描述

Android 12+ 新增 仅本次使用

在这里插入图片描述

3.2 iOS 权限弹窗(截图描述)

在这里插入图片描述

iOS 隐私指示器(顶部状态栏):

  • 绿点:相机正在使用

  • 橙点:麦克风正在使用

  • 蓝点:定位正在使用

3.3 HarmonyOS 授权弹窗(最细粒度)

鸿蒙默认 临时授权,界面如下:

┌─────────────────────────┐
│ 允许使用相机?           │
│ 临时允许 │ 单次允许 │ 拒绝
│ 1小时|1天|始终允许
└─────────────────────────┘

鸿蒙不提供 “全局相册授权”,只能用系统相册选择器,应用无法遍历相册


四、完整可运行示例代码(大量增强)

4.1 Android 完整权限代码(Kotlin)

包含:检查、申请、回调、不再询问、跳转设置

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class PermissionDemoActivity : AppCompatActivity() {

    private val REQ_CAMERA = 100
    private val REQ_LOCATION = 101

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_permission_demo)

        // 检查相机权限
        checkCameraPermission()
    }

    // 检查相机权限
    private fun checkCameraPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
            == PackageManager.PERMISSION_GRANTED
        ) {
            // 已授权
            openCamera()
        } else {
            // 申请权限
            ActivityCompat.requestPermissions(
                this, arrayOf(Manifest.permission.CAMERA), REQ_CAMERA
            )
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            REQ_CAMERA -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    openCamera()
                } else {
                    // 用户拒绝
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(
                            this, Manifest.permission.CAMERA
                        )) {
                        // 勾选了“不再询问”
                        Toast.makeText(this, "请前往设置开启权限", Toast.LENGTH_SHORT).show()
                        goToAppSetting()
                    }
                }
            }
        }
    }

    private fun openCamera() {
        Toast.makeText(this, "相机已授权", Toast.LENGTH_SHORT).show()
    }

    // 跳转到应用设置
    private fun goToAppSetting() {
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
            data = Uri.fromParts("package", packageName, null)
        }
        startActivity(intent)
    }
}

4.2 iOS 完整权限代码(Swift)

包含:相机、定位、相册

import UIKit
import AVFoundation
import CoreLocation
import Photos

class PermissionVC: UIViewController, CLLocationManagerDelegate {

    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        requestCamera()
    }

    // 相机权限
    func requestCamera() {
        AVCaptureDevice.requestAccess(for: .video) { granted in
            if granted {
                print("相机授权成功")
            } else {
                print("用户拒绝相机")
            }
        }
    }

    // 定位权限(使用期间)
    func requestLocation() {
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
    }

    // 相册权限(有限访问)
    func requestPhoto() {
        PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
            if status == .authorized || status == .limited {
                print("相册授权成功/有限访问")
            }
        }
    }

    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        let status = manager.authorizationStatus
        if status == .authorizedWhenInUse {
            print("定位授权")
        }
    }
}

4.3 HarmonyOS 完整权限代码(ArkTS)

包含:权限申请 + 相册安全选择器

import UIAbility from '@ohos.app.ability.UIAbility';
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import picker from '@ohos.file.picker';
import { BusinessError } from '@ohos.base';

export default class EntryAbility extends UIAbility {
  async onCreate(want, launchParam) {

    let atManager = abilityAccessCtrl.createAtManager();
    let permissions = ['ohos.permission.CAMERA'];

    // 检查权限
    try {
      let grantStatus = await atManager.checkAccessToken(this.context.applicationInfo.name, permissions);

      if (grantStatus[0] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
        console.log('相机已授权');
      } else {
        // 申请权限
        await atManager.requestPermissionsFromUser(this.context, permissions);
      }
    } catch (err) {
      console.error('权限申请失败');
    }

    // 鸿蒙安全相册选择器(无法获取全部相册)
    this.openPhotoPicker();
  }

  // 打开系统相册选择器
  async openPhotoPicker() {
    let photoPicker = new picker.PhotoViewPicker();
    let res = await photoPicker.select({
      PhotoSelectOptions: { maxSelectNumber: 1 }
    });
    console.log('选中照片:', res[0]);
    // 应用只能拿到 URI,无法遍历整个相册
  }
}

五、系统权限设置页截图描述(CSDN 必备)

5.1 Android 权限设置页

【权限管理】
• 位置信息
  - 允许
  - 仅使用期间允许
  - 禁止
• 相机
• 麦克风
• 存储
• 通讯录
• 后台权限管理

5.2 iOS 权限设置页

隐私与安全性
→ 相机 → XX App → 开启/关闭
→ 照片 → 允许全部/选中照片/关闭
→ 定位 → 精确位置开关

5.3 HarmonyOS 权限设置页

权限管理
→ 相机
  - 临时允许
  - 单次允许
  - 1小时/1天/始终
→ 权限使用记录
→ 异常权限调用提醒

六、权限调用日志与隐私指示器(截图描述)

Android 隐私黑匣子(Android 15)

权限使用记录:
14:23  XXApp 使用位置信息
14:25  XXApp 使用相机
15:00  XXApp 后台尝试调用麦克风(已拦截)

iOS 顶部指示器

[时间] 绿点  相机被调用
[时间] 橙点  麦克风被调用

HarmonyOS 权限实时提醒

顶部小图标:
🔒 权限安全访问
📷 相机正在使用
🌍 位置正在使用

七、三大系统权限机制深度对比表

对比项 Android iOS HarmonyOS
授权粒度 功能级 功能级 + 部分数据级 数据级 + 场景级 + 时长级
临时授权 仅本次使用(部分权限) 全权限默认支持
后台权限 独立申请,管控较松 严格,5 分钟自动失效 默认禁止,需双重验证
相册访问 授权后可遍历 可限制选中照片 只能选,无法遍历
跨设备权限 接力 分布式原生支持
权限自动回收 强(临时 / 时长到期回收)
内核隔离 极高(微内核)

八、典型权限漏洞与风险

Android

  • 路径穿越漏洞访问其他应用数据

  • 利用保活机制持续后台定位

  • 厂商定制弱化 SELinux 导致权限逃逸

iOS

  • TCC 数据库注入篡改授权状态

  • 始终定位导致轨迹泄露

  • 应用间共享数据权限校验不严

HarmonyOS

  • 兼容 Android 应用沿用旧权限模型

  • 分布式跨设备授权链路存在理论风险

  • 部分三方应用未适配导致权限异常


九、开发者最佳实践(可直接写进项目规范)

Android

  • 必须适配 Scoped Storage

  • 处理 “不再询问” 场景并跳转设置

  • 不滥用后台位置、麦克风

iOS

  • 权限描述必须真实详细,否则审核被拒

  • 优先使用 \.limited 相册授权

HarmonyOS

  • 不申请全局数据权限

  • 全部使用系统 Picker 访问隐私数据

  • 前台 / 后台权限严格分离


十、总结

  • Android:开放灵活,但安全最弱,碎片化严重

  • iOS:统一严格,体验一致,数据保护中等

  • HarmonyOS数据主权设计最超前,细粒度、临时化、可回收、跨设备可信代表未来方向

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐