鴻蒙OS 權(quán)限開發(fā)指導(dǎo)

2020-09-18 14:47 更新

場(chǎng)景介紹

HarmonyOS 支持開發(fā)者自定義權(quán)限來保護(hù)能力或接口,同時(shí)開發(fā)者也可申請(qǐng)權(quán)限來訪問受權(quán)限保護(hù)的對(duì)象。

權(quán)限申請(qǐng)

開發(fā)者需要在 config.json 文件中的“reqPermissions”字段中聲明所需要的權(quán)限。

{
    "reqPermissions": [{
        "name": "ohos.permission.CAMERA",
        "reason": "$string:permreason_camera",
        "usedScene": {
            "ability": ["com.mycamera.Ability", "com.mycamera.AbilityBackground"],
            "when": "always"
        }
    },{
    ...
    }]
}

權(quán)限申請(qǐng)格式采用數(shù)組格式,可支持同時(shí)申請(qǐng)多個(gè)權(quán)限,權(quán)限個(gè)數(shù)最多不能超過 1024 個(gè)。

值說明 類型 取值范圍 默認(rèn)值 規(guī)則約束
name 必須,填寫需要使用的權(quán)限名稱。 字符串 自定義 未填寫時(shí),解析失敗。
reason 可選,當(dāng)申請(qǐng)的權(quán)限為 user_grant 權(quán)限時(shí)此字段必填。描述申請(qǐng)權(quán)限的原因。 字符串 顯示文字長(zhǎng)度不能超過 256 個(gè)字節(jié)。 user_grant 權(quán)限必填,否則不允許在應(yīng)用市場(chǎng)上架。需做多語種適配。
usedScene 可選,當(dāng)申請(qǐng)的權(quán)限為 user_grant 權(quán)限時(shí)此字段必填。描述權(quán)限使用的場(chǎng)景和時(shí)機(jī)。場(chǎng)景類型有:ability、when(調(diào)用時(shí)機(jī))。可配置多個(gè)ability。 ability:字符串?dāng)?shù)組 when:字符串 ability:ability 的名稱 when:inuse(使用時(shí))、always(始終) ability:空 when:inuse user_grant權(quán)限必填 ability,可選填when。

如果聲明使用的權(quán)限的 grantMode 是 system_grant, 則權(quán)限會(huì)在當(dāng)應(yīng)用安裝的時(shí)候被自動(dòng)授予。

如果聲明使用的權(quán)限的 grantMode 是 user_grant,則必須經(jīng)用戶手動(dòng)授權(quán)(用戶在彈框中授權(quán)或進(jìn)入權(quán)限設(shè)置界面授權(quán))才可使用。用戶會(huì)看到 reason 字段中填寫的理由,來幫助用戶決定是否給予授權(quán)。

說明

對(duì)于授權(quán)方式為 user_grant 的權(quán)限,每一次執(zhí)行需要這一權(quán)限的操作時(shí),都需要檢查自身是否有該權(quán)限。當(dāng)自身具有權(quán)限時(shí),才可繼續(xù)執(zhí)行,否則應(yīng)用需要請(qǐng)求用戶授予權(quán)限。示例參見[動(dòng)態(tài)申請(qǐng)權(quán)限開發(fā)步驟]。

自定義權(quán)限

開發(fā)者需要在 config.json 文件中的“defPermissions”字段中自定義所需的權(quán)限:

{
    "defPermissions": [{
        "name": "com.myability.permission.MYPERMISSION",
        "grantMode": "system_grant",
        "availableScope": ["signature"]
    }, {
    ...
    }]
}

權(quán)限定義格式采用數(shù)組格式,可支持同時(shí)定義多個(gè)權(quán)限,自定義的權(quán)限個(gè)數(shù)最多不能超過 1024個(gè)。權(quán)限定義的字段描述詳見[表2]。

值說明 類型 取值范圍 默認(rèn)值 規(guī)則約束
name 必填,權(quán)限名稱。為最大可能避免重名,采用反向域公司名+應(yīng)用名+權(quán)限名組合。 字符串 自定義 第三方應(yīng)用不允許填寫系統(tǒng)存在的權(quán)限,否則安裝失敗。未填寫解析失敗。權(quán)限名長(zhǎng)度不能超過 256 個(gè)字符。
grantMode 必填,權(quán)限授予方式。 字符串 user_grant(用戶授權(quán))system_grant(系統(tǒng)授權(quán))取值含義參見:[表3]。 system_grant 未填值或填寫了取值范圍以外的值時(shí),自動(dòng)賦予默認(rèn)值;不允許第三方應(yīng)用填寫 user_grant,填寫后會(huì)自動(dòng)賦予默認(rèn)值。
availableScope 選填,權(quán)限限制范圍。不填則表示此權(quán)限對(duì)所有應(yīng)用開放。 字符串?dāng)?shù)組 signatureprivilegedrestricted 可參見。取值含義請(qǐng)見:[表4]。 填寫取值范圍以外的值時(shí),權(quán)限限制范圍不生效。由于第三方應(yīng)用并不在 restricted 的范圍內(nèi),很少會(huì)出現(xiàn)權(quán)限定義者不能訪問自身定義的權(quán)限的情況,所以不允許三方應(yīng)用填寫restricted。
label 選填,權(quán)限的簡(jiǎn)短描述,若未填寫,則使用到簡(jiǎn)短描述的地方由權(quán)限名取代。 字符串 自定義 需要多語種適配。
description 選填,權(quán)限的詳細(xì)描述,若未填寫,則使用到詳細(xì)描述的地方由 label 取代。 字符串 自定義 需要多語種適配。

授予方式(grantMode) 說明 自定義權(quán)限是否可指定該級(jí)別 取值樣例
system_grant 在“config.json”里面聲明,安裝后系統(tǒng)自動(dòng)授予。 GET_NETWORK_INFO 、GET_WIFI_INFO
user_grant 在“config.json”里面聲明,并在使用時(shí)動(dòng)態(tài)申請(qǐng),用戶授權(quán)后才可使用。 否,如自定義則強(qiáng)制修改為 system_grant。 CAMERA、MICROPHONE

權(quán)限范圍(availableScope) 說明 自定義權(quán)限是否可指定該級(jí)別 取值樣例
restricted 需要開發(fā)者向華為申請(qǐng)后才能被使用的特殊權(quán)限。 ANSWER_CALL、READ_CALL_LOG、RECEIVE_SMS
signature 權(quán)限定義方和使用方的簽名一致。需在“config.json”里面聲明后,由權(quán)限管理模塊負(fù)責(zé)簽名校驗(yàn)一致后,可使用。 對(duì)應(yīng)用(或 Ability)操作的系統(tǒng)接口上由系統(tǒng)定義權(quán)限以及應(yīng)用自定義的權(quán)限。如:find某Ability,連接某Ability。
privileged 預(yù)置在系統(tǒng)版本中的特權(quán)應(yīng)用可申請(qǐng)的權(quán)限。 SET_TIME、MANAGE_USER_STORAGE

訪問權(quán)限控制

  • Ability的訪問權(quán)限控制

在 config.json 中填寫“abilities”到“permissions”字段,即只有擁有該權(quán)限的應(yīng)用可訪問此Ability。下面的例子表明只有擁有“ohos.permission.CAMERA”權(quán)限的應(yīng)用可以訪問此ability。

  "abilities": [{
          "name": ".MainAbility",
          "description": "$string:description_main_ability",
          "icon": "$media:hiworld.png",
          "label": "HiCamera",
          "launchType": "standard",
          "orientation": "portrait",
          "visible": false,
          "permissions": [
              "ohos.permission.CAMERA"
          ],
      }]
值說明 類型 取值范圍 默認(rèn)值 規(guī)則約束
permissions 選填,權(quán)限名稱。用以表示此 ability 受哪個(gè)權(quán)限保護(hù),即只有擁有此權(quán)限的應(yīng)用可訪問此 ability。 字符串 自定義 目前僅支持填寫一個(gè)權(quán)限名,若填寫多個(gè)權(quán)限名,僅第一個(gè)權(quán)限名稱有效。

  • Ability 接口的訪問權(quán)限控制

在 Ability 實(shí)現(xiàn)中,如需要對(duì)特定接口對(duì)調(diào)用者做訪問控制,可在服務(wù)側(cè)的接口實(shí)現(xiàn)中,主動(dòng)通過 verifyCallingPermission、 verifyCallingOrSelfPermission 來檢查訪問者是否擁有所需要的權(quán)限。

  if (verifyCallingPermission("ohos.permission.CAMERA") != IBundleManager.PERMISSION_GRANTED) {
      // 調(diào)用者無權(quán)限,做錯(cuò)誤處理
  }
      // 調(diào)用者權(quán)限校驗(yàn)通過,開始提供服務(wù)

API接口說明

接口原型 接口詳細(xì)描述
public int verifyPermission(String permissionName, int pid, int uid) 接口功能:查詢指定 PID、UID 的應(yīng)用是否已被授予某權(quán)限輸入?yún)?shù):permissionName:權(quán)限名;pid:進(jìn)程id;uid:uid 輸出參數(shù):無返回值: IBundleManager.PERMISSION_DENIED、IBundleManager.PERMISSION_GRANTED
public int verifyCallingPermission(String permissionName) 接口功能:查詢 IPC 跨進(jìn)程調(diào)用方的進(jìn)程是否已被授予某權(quán)限輸入?yún)?shù):permissionName:權(quán)限名輸出參數(shù):無返回值: IBundleManager.PERMISSION_DENIED、IBundleManager.PERMISSION_GRANTED
public int verifySelfPermission(String permissionName) 接口功能:查詢自身進(jìn)程是否已被授予某權(quán)限輸入?yún)?shù):permissionName:權(quán)限名輸出參數(shù):無返回值: IBundleManager.PERMISSION_DENIED、IBundleManager.PERMISSION_GRANTED
public int verifyCallingOrSelfPermission(String permissionName) 接口功能:當(dāng)有遠(yuǎn)端調(diào)用檢查遠(yuǎn)端是否有權(quán)限,否則檢查自身是否擁有權(quán)限輸入?yún)?shù):permissionName:權(quán)限名輸出參數(shù):無返回值: IBundleManager.PERMISSION_DENIED、IBundleManager.PERMISSION_GRANTED
public boolean canRequestPermission(String permissionName) 接口功能:向系統(tǒng)權(quán)限管理模塊查詢某權(quán)限是否不再彈框授權(quán)了輸入?yún)?shù):permissionName:權(quán)限名輸出參數(shù):無返回值:true 允許彈框,false 不允許彈框
void requestPermissionsFromUser (String[] permissions, int requestCode) 接口功能:向系統(tǒng)權(quán)限管理模塊申請(qǐng)權(quán)限(接口可支持一次申請(qǐng)多個(gè)。若下一步操作涉及到多個(gè)敏感權(quán)限,可以這么用,其他情況建議不要這么用。因?yàn)閺椏蜻€是按權(quán)限組一個(gè)個(gè)去彈框,耗時(shí)比較長(zhǎng)。用到哪個(gè)權(quán)限就去申請(qǐng)哪個(gè))輸入?yún)?shù): permissionNames:權(quán)限名列表;requestCode: 請(qǐng)求應(yīng)答會(huì)帶回此編碼以匹配本次申請(qǐng)的權(quán)限請(qǐng)求輸出參數(shù):無返回值:無
void onRequestPermissionsFromUserResult (int requestCode, String[] permissions, int[] grantResults) 接口功能:調(diào)用 requestPermissionsFromUser 后的應(yīng)答接口輸入?yún)?shù):requestCode:requestPermission 中傳入的requestCode;permissions:申請(qǐng)的權(quán)限名;grantResults:申請(qǐng)權(quán)限的結(jié)果輸出參數(shù):無返回值:無

動(dòng)態(tài)申請(qǐng)權(quán)限開發(fā)步驟

  1. 在 config.json 文件中聲明所需要的權(quán)限。

   {
       " reqPermissions": [{
           "name": "ohos.permission.CAMERA",
           "reason": "$string:permreason_camera",
           "usedScene": {
               "ability": ["com.mycamera.Ability", "com.mycamera.AbilityBackground"],
               "when": "always"}
           }, {
           ...
           }]
       }]
   }

  1. 使用 ohos.app.Context.verifySelfPermission 接口查詢應(yīng)用是否已被授予該權(quán)限。

  • 如果已被授予權(quán)限,可以結(jié)束權(quán)限申請(qǐng)流程。
  • 如果未被授予權(quán)限,繼續(xù)執(zhí)行下一步。

  1. 使用 canRequestPermission 查詢是否可動(dòng)態(tài)申請(qǐng)。

  • 如果不可動(dòng)態(tài)申請(qǐng),說明已被用戶或系統(tǒng)永久禁止授權(quán),可以結(jié)束權(quán)限申請(qǐng)流程。
  • 如果可動(dòng)態(tài)申請(qǐng),繼續(xù)執(zhí)行下一步。

  1. 使用 requestPermissionFromUser 動(dòng)態(tài)申請(qǐng)權(quán)限,通過回調(diào)函數(shù)接受授予結(jié)果。

樣例代碼如下:

   if (verifySelfPermission("ohos.permission.CAMERA") != IBundleManager.PERMISSION_GRANTED) {
       // 應(yīng)用未被授予權(quán)限
       if (canRequestPermission("ohos.permission.CAMERA")) {
           // 是否可以申請(qǐng)彈框授權(quán)(首次申請(qǐng)或者用戶未選擇禁止且不再提示)
           requestPermissionsFromUser(
                   new String[] { "ohos.permission.CAMERA" } , MY_PERMISSIONS_REQUEST_CAMERA);
       } else {
           // 顯示應(yīng)用需要權(quán)限的理由,提示用戶進(jìn)入設(shè)置授權(quán)
       }
   } else {
       // 權(quán)限已被授予
   }

    
   @override
   public void onRequestPermissionsFromUserResult (int requestCode, String[] permissions, int[] grantResults){
       switch (requestCode) {
           case MY_PERMISSIONS_REQUEST_CAMERA: {
               // 匹配requestPermissions的requestCode
               if (grantResults.length > 0
                   && grantResults[0] == IBundleManager.PERMISSION_GRANTED) {
                   // 權(quán)限被授予
                   // 注意:因時(shí)間差導(dǎo)致接口權(quán)限檢查時(shí)有無權(quán)限,所以對(duì)那些因無權(quán)限而拋異常的接口進(jìn)行異常捕獲處理
               } else {
                   // 權(quán)限被拒絕
               }
               return;
           }
       }
   }
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)