HarmonyOS学习(十一)——安全管理


官方文档地址: 应用权限管控概述-应用权限管控-程序访问控制-安全-系统 - 华为HarmonyOS开发者 (huawei.com)

1、权限等级划分

根据权限对于不同等级应用有不同的开放范围,权限类型对应分为以下三个等级,等级依次提高

APL级别说明开放范围
normal允许应用访问超出默认规则外的普通系统资源,如配置Wi-Fi信息、调用相机拍摄等。
这些系统资源的开放(包括数据和功能)对用户隐私以及其他应用带来的风险低。
APL等级为normal及以上的应用。
system_basic允许应用访问操作系统基础服务(系统提供或者预置的基础功能)相关的资源,如系统设置、身份认证等。
这些系统资源的开放对用户隐私以及其他应用带来的风险较高。
- APL等级为system_basic及以上的应用。
- 部分权限对normal级别的应用受限开放,这部分权限在本指导中描述为“受限开放权限”。
system_core涉及开放操作系统核心资源的访问操作。这部分系统资源是系统最核心的底层服务,如果遭受破坏,操作系统将无法正常运行。- APL等级为system_core的应用。
- 仅对系统应用开放。
2、权限类型

根据授权方式的不同,权限类型可分为system_grant(系统授权)和user_grant(用户授权)

system_grant(系统授权)

system_grant指的是系统授权类型,在该类型的权限许可下,应用被允许访问的数据不会涉及到用户或设备的敏感信息,应用被允许执行的操作对系统或者其他应用产生的影响可控。

如果在应用中申请了system_grant权限,那么系统会在用户安装应用时,自动把相应权限授予给应用。

user_grant(用户授权)

user_grant指的是用户授权类型,在该类型的权限许可下,应用被允许访问的数据将会涉及到用户或设备的敏感信息,应用被允许执行的操作可能对系统或者其他应用产生严重的影响。

该类型权限不仅需要在安装包中申请权限,还需要在应用动态运行时,通过发送弹窗的方式请求用户授权。在用户手动允许授权后,应用才会真正获取相应权限,从而成功访问操作目标对象。

3、动态申请权限列表单
权限名称权限级别权限说明
ohos.permission.ANSWER_CALLsystem_basic允许应用接听来电
ohos.permission.READ_CALENDARsystem_basic允许应用读取日历信息
ohos.permission.READ_CALL_LOGsystem_basic允许应用读取通话记录
ohos.permission.READ_CELL_MESSAGEsystem_basic允许应用读取设备收到的广播信息
ohos.permission.READ_CONTACTSsystem_basic允许应用读取联系人护具
ohos.permission.READ_MESSAGEsystem_basic允许应用读取短信息
ohos.permission.RECEIVE_MMSsystem_basic允许应用接受和处理彩信
ohos.permission.RECEIVE_SMSsystem_basic允许应用接受和处理短信
ohos.permission.RECEIVE_WAP_MESSAGEsystem_basic允许应用接收和处理Wap消息
ohos.permission.MICROPHONEnormal允许应用使用麦克风
ohos.permission.SEND_MESSAGEsystem_basic允许应用发送短信
ohos.permission.WRITE_CALENDARnormal允许应用添加、移除或者更改日历活动
ohos.permission.WRITE_CALL_LOGsystem_basic允许应用添加、移除或更改通话记录
ohos.permission.WRITE_CONTACTSsystem_basic允许应用添加、移除或者更改联系人数据
ohos.permission.DISTRIBUTED_DATASYNCnormal允许不同设备间的数据交换
ohos.permission.MANAGE_VOICEMAILsystem_basic允许应用在语音信箱中留言
ohos.permission.LOCAL_IN_BACKGROUNDnormal允许应用在后台运行时获取设备位置信息
ohos.permission.LOCATIONnormal允许应用获取设备位置信息
ohos.permission.APPROXIMATELY_LOCATIONnormal允许应用获取设备模糊位置信息
ohos.permission.MEDIA_LOCATIONnormal允许应用访问用户媒体文件中的地理位置信息
ohos.permission.CAMERAnormal允许应用使用相机拍摄照片和录制视频
ohos.permission.READ_MEDIAnormal允许应用读取用户外部存储中的媒体文件信息
ohos.permission.WRITE_MEDIAnormal允许应用读写用户外部存储中的媒体文件信息
ohos.permission.ACTIVITY_MOTIONnormal允许应用读取用户当前的运动状态
ohos.permission.READ_HEALTH_DATAnormal允许应用读取用户的健康数据
4、访问控制开发步骤

如果应用需要获取目标权限,需要先进行权限申请。

  • 权限申请:开发者需要在配置文件中声明目标权限。
  • 权限授权:如果目标权限是system_grant类型,开发者在进行权限申请后,系统会在安装应用时为其进行权限授予,开发者不需要进行其他操作即可使用权限。如果目标权限是user_grant时,开发者在进行权限申请后,在运行时触发动态弹窗,请求用户授权。
4.1、权限申请

应用需要在工程配置文件中对需要的权限逐个神功,没有在配置文件中声明的权限,应用将无法获得授权。

{
  "module":{
    "requestPermissions": [
        {
          "name": "ohos.permission.INTERNET",
          "reason":"$string:Permission_internet_reason",
          "usedScene": {
              "abilities": ["PermissionDemoAbility"],
              "when": "inuse"
          }
        },
        {
          "name": "ohos.permission.CAMERA",
          "reason": "$string:Permission_camera_reason",
          "usedScene": {
            "abilities": ["PermissionDemoAbility"],
            "when": "always"
          }
        }
    ]
  }
}
name权限名称
reason当申请权限为user_grant时,此字段必填,描述申请权限的原因
usedscreen当申请权限为user_grant时,此字段必填,描述权限使用的场景和时机
abilities标识需要使用该权限的Ability,为数组
when标识权限使用的时机,inuse/always,标识仅允许前台使用和前后台都可以使用
5、实战:访问Camera授权
5.1、申请ohos.permission.Camera权限
{
  "name": "ohos.permission.CAMERA",
  "reason": "$string:Permission_camera_reason",
  "usedScene": {
    "abilities": ["PermissionDemoAbility"],
    "when": "always"
  }
}
5.2、校验当前是否已经授权

在进行权限申请之前,需要先检查当前应用程序是否已经被授予权限。可以通过调用checkAccessToken()方法来校验当前是否已经授权。如果已经授权,则可以直接访问目标操作,否则需要进行下一步操作,即向用户申请授权。

checkAccessToken(tokenID: number, permissionName: Permissions): Promise

参数名类型必填说明
tokenIDnumber要校验的目标应用的身份标识。可通过应用的ApplicationInfo的accessTokenId字段获得。
permissionNamePermissions需要校验的权限名称,合法的权限名取值可在应用权限列表中查询。
const permissions:Array<Permissions> = ["ohos.permission.CAMERA"]

//检查权限
async function checkPermissionGrant(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;

  // 获取应用程序的accessTokenID
  let tokenId: number = 0;
  try {
    let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
    tokenId = appInfo.accessTokenId;
  } catch (error) {
    // @ts-ignore
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
  }

  // 校验应用是否被授予权限
  try {
    grantStatus = await atManager.checkAccessToken(tokenId, permission);
  } catch (error) {
    // @ts-ignore
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
  }

  return grantStatus;
}

async function checkPermissions(): Promise<void> {
  let grantStatus: abilityAccessCtrl.GrantStatus = await checkPermissionGrant(permissions[0]);

  if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
    // 已经授权,可以继续访问目标操作
    hilog.error(0x0000,'check_permission',"获取到Camera权限")
  } else {
    // 申请麦克风权限
    hilog.error(0x0000,'check_permission',"Camera权限未被授予")
  }
}

5.3、请求权限
// 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
  atManager.requestPermissionsFromUser(context, permissions).then((data) => {
    let grantStatus: Array<number> = data.authResults;
    let length: number = grantStatus.length;
    for (let i = 0; i < length; i++) {
      if (grantStatus[i] === 0) {
        // 用户授权,可以继续访问目标操作
      } else {
        // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
        return;
      }
    }
    // 授权成功
    // @ts-ignore
  }).catch((err: BusinessError) => {
    console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
  })
}

5.4、在UI中进行权限声明
import common from '@ohos.app.ability.common';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';



const permissions: Array<Permissions> = ['ohos.permission.CAMERA'];
// 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
  atManager.requestPermissionsFromUser(context, permissions).then((data) => {
    let grantStatus: Array<number> = data.authResults;
    let length: number = grantStatus.length;
    for (let i = 0; i < length; i++) {
      if (grantStatus[i] === 0) {
        // 用户授权,可以继续访问目标操作
      } else {
        // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
        return;
      }
    }
    // 授权成功
    // @ts-ignore
  }).catch((err: BusinessError) => {
    console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
  })
}


@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  aboutToAppear() {
    // 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
    const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
    reqPermissionsFromUser(permissions, context);
  }

  build() {

    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值