OpenHarmony應(yīng)用訪問控制權(quán)限申請(qǐng)開發(fā)范例
想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:
概念介紹
在應(yīng)用首次啟動(dòng)時(shí),我們常常遇到,需要申請(qǐng)授權(quán)才能使用應(yīng)用的完整功能,比如在應(yīng)用首次啟動(dòng)時(shí),會(huì)彈窗申請(qǐng)開啟位置權(quán)限、申請(qǐng)相機(jī)權(quán)限等,如圖所示。本文就以橘子購(gòu)物示例應(yīng)用為例,來講解OpenHarmony應(yīng)用首次啟動(dòng)申請(qǐng)授權(quán)相關(guān)的技術(shù)點(diǎn)。
OpenHarmony應(yīng)用框架提供了200+應(yīng)用權(quán)限,在權(quán)限列表文件中,我們可以看到每種權(quán)限有不同的APL級(jí)別、權(quán)限類型、ACL使能信息,如下所示。我們先看下應(yīng)用權(quán)限相關(guān)的幾個(gè)概念。
ohos.permission.WRITE_CONTACTS
允許應(yīng)用添加、移除或更改聯(lián)系人數(shù)據(jù)。
權(quán)限級(jí)別:system_basic
授權(quán)方式:user_grant
ACL使能:TRUE
- 應(yīng)用APL等級(jí)
元能力權(quán)限等級(jí)APL(Ability Privilege Level)指的是應(yīng)用的權(quán)限申請(qǐng)優(yōu)先級(jí)的定義,不同APL等級(jí)的應(yīng)用能夠申請(qǐng)的權(quán)限等級(jí)不同。
應(yīng)用的等級(jí)可以分為三個(gè)等級(jí),如下表。默認(rèn)情況下,應(yīng)用的APL等級(jí)都為normal等級(jí)。權(quán)限列表中的權(quán)限級(jí)別指的就是APL等級(jí),應(yīng)用:
APL級(jí)別 | 說明 |
system_core | 該等級(jí)的應(yīng)用服務(wù)提供操作系統(tǒng)核心能力。 |
system_basic | 該等級(jí)的應(yīng)用服務(wù)提供系統(tǒng)基礎(chǔ)服務(wù)。 |
normal | 普通應(yīng)用。 |
- 權(quán)限類型
根據(jù)授權(quán)方式的不同,權(quán)限類型可分為system_grant(系統(tǒng)授權(quán))和user_grant(用戶授權(quán))。對(duì)應(yīng)權(quán)限列表中的授權(quán)方式。
- 訪問控制列表(ACL)
每個(gè)應(yīng)用權(quán)限中的權(quán)限級(jí)別和應(yīng)用的APL等級(jí)是一一對(duì)應(yīng)的。原則上,擁有低APL等級(jí)的應(yīng)用默認(rèn)無法申請(qǐng)更高等級(jí)的權(quán)限。訪問控制列表ACL(Access Control List)提供了解決低等級(jí)應(yīng)用訪問高等級(jí)權(quán)限問題的特殊渠道。
橘子購(gòu)物示例應(yīng)用首次啟動(dòng)申請(qǐng)權(quán)限的示例圖:
OpenHarmony應(yīng)用訪問控制權(quán)限申請(qǐng)開發(fā)范例-開源基礎(chǔ)軟件社區(qū)
配置文件
了解了權(quán)限相關(guān)的概念,我們看下權(quán)限相關(guān)的配置文件。
module.json5配置文件
應(yīng)用需要在項(xiàng)目的module.json5配置文件中逐個(gè)聲明所需的權(quán)限,否則應(yīng)用將無法獲取授權(quán)。不管是什么授權(quán)方式,system_grant(系統(tǒng)授權(quán))還是user_grant(用戶授權(quán))都需要在配置文件中聲明。
在配置文件的requestPermissions屬性數(shù)組中配置所需的權(quán)限,包含3個(gè)屬性:name、reason和usedScene。
其中:
- name 指定權(quán)限名稱,是必填項(xiàng)。
- reason 描述申請(qǐng)權(quán)限的原因,可選項(xiàng)。
- usedScene 描述權(quán)限使用的場(chǎng)景和時(shí)機(jī),可選項(xiàng)。
- abilities:標(biāo)識(shí)需要使用到該權(quán)限的Ability,標(biāo)簽為數(shù)組形式??蛇x項(xiàng)。
- when:標(biāo)識(shí)權(quán)限使用的時(shí)機(jī),值為inuse/always。inuse:表示為僅允許前臺(tái)使用;always:表示前后臺(tái)都可使用。
應(yīng)用默認(rèn)的權(quán)限等級(jí)為normal。如果應(yīng)用需要申請(qǐng)高于默認(rèn)等級(jí)的權(quán)限,除了在配置文件中進(jìn)行聲明之外,還需要通過ACL方式進(jìn)行聲明使用。下文會(huì)介紹。
module.json5配置文件片段如下:
{
"module" : {
...
"requestPermissions":[
{
"name" : "ohos.permission.PERMISSION1",
"reason": "$string:reason",
"usedScene": {
"abilities": [
"FormAbility"
],
"when":"inuse"
}
},
...
]
}
}
HarmonyAppProvision配置文件
應(yīng)用默認(rèn)權(quán)限等級(jí)normal,當(dāng)應(yīng)用需要申請(qǐng)system_basic和system_core等級(jí)的權(quán)限時(shí),也就是說,如果需要申請(qǐng)的權(quán)限等級(jí)高于應(yīng)用默認(rèn)的等級(jí),需要使用ACL方式聲明使用。
例如,如果應(yīng)用需要訪問用戶公共目錄中的音樂文件,需要申請(qǐng)ohos.permission.WRITE_AUDIO權(quán)限,該權(quán)限屬于system_basic等級(jí)。如果應(yīng)用需要截取屏幕圖像,則需要申請(qǐng)ohos.permission.CAPTURE_SCREEN權(quán)限,該權(quán)限屬于system_core等級(jí)。此時(shí),需要將相關(guān)權(quán)限項(xiàng)配置到HarmonyAppProvision配置文件的ACL字段中。
HarmonyAppProvision配置文件用于配置應(yīng)用的權(quán)限、簽名信息等,該文件位置在:`OpenHarmony SDK目錄>Toolchains>{Version}>lib>UnsgnedReleasedProfileTemplate.json”。
UnsgnedReleasedProfileTemplate.json配置文件片段如下:
{
// ...
"acls":{
"allowed-acls":[
"ohos.permission.WRITE_AUDIO",
"ohos.permission.CAPTURE_SCREEN"
]
}
}
開發(fā)步驟
我們來看橘子應(yīng)用權(quán)限部分是如何開發(fā)的。
權(quán)限配置文件
配置文件module.json5非常簡(jiǎn)單,只提供了需要的權(quán)限的名稱,如下所示。
這些權(quán)限的授權(quán)方式,有的是system_grant(系統(tǒng)授權(quán))也有user_grant(用戶授權(quán)),都在配置文件中進(jìn)行了聲明。
需要注意的是,權(quán)限"ohos.permission.CAPTURE_SCREEN"的APL權(quán)限級(jí)別是system_core。
ohos.permission.CAPTURE_SCREEN
允許應(yīng)用截取屏幕圖像。
權(quán)限級(jí)別:system_core
授權(quán)方式:system_grant
ACL使能:TRUE
為了正常使用該權(quán)限,需要在OpenHarmony SDK目錄下的toolchains\lib\UnsgnedReleasedProfileTemplate.json文件內(nèi)進(jìn)行ACL權(quán)限配置:
"acls":{
"allowed-acls":[
"ohos.permission.CAPTURE_SCREEN"
]
},
文件module.json5片段:
"requestPermissions": [
{
"name": "ohos.permission.CAMERA"
},
{
"name": "ohos.permission.LOCATION"
},
{
"name": "ohos.permission.VIBRATE"
},
{
"name": "ohos.permission.LOCATION_IN_BACKGROUND"
},
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.CAPTURE_SCREEN"
},
{
"name": "ohos.permission.READ_MEDIA"
},
{
"name": "ohos.permission.WRITE_MEDIA"
},
{
"name": "ohos.permission.MEDIA_LOCATION"
}
]
代碼實(shí)現(xiàn)
我們?cè)倏聪孪蛴脩羰跈?quán)的代碼如何實(shí)現(xiàn)。
當(dāng)應(yīng)用需要訪問用戶的隱私信息或使用系統(tǒng)能力時(shí),例如獲取位置信息、訪問日歷、使用相機(jī)拍攝照片或錄制視頻等,應(yīng)該向用戶請(qǐng)求授權(quán)。這需要使用 user_grant 類型權(quán)限。
在此之前,應(yīng)用需要進(jìn)行權(quán)限校驗(yàn),以判斷當(dāng)前調(diào)用者是否具備所需的權(quán)限。如果權(quán)限校驗(yàn)結(jié)果表明當(dāng)前應(yīng)用尚未被授權(quán)該權(quán)限,則應(yīng)使用動(dòng)態(tài)彈框授權(quán)方式,為用戶提供手動(dòng)授權(quán)的入口。
在橘子購(gòu)物示例應(yīng)用中,向用戶授權(quán)的代碼實(shí)現(xiàn)在MainAbility的onCreate函數(shù)內(nèi)。
需要向用戶授權(quán)的這些權(quán)限的授權(quán)方式需要為user_grant,如果是system_grant,則不需要向用戶權(quán)限,比如’ohos.permission.INTERNET’是不必要的。
另外,向用戶授權(quán)的這些權(quán)限需要配置在module.json5配置文件內(nèi)。
橘子購(gòu)物示例應(yīng)用只是簡(jiǎn)單演示動(dòng)態(tài)彈窗授權(quán),并沒有復(fù)雜的邏輯。
如果需要深入了解用戶授權(quán),建議進(jìn)一步了解下API接口:
- requestPermissionsFromUser
動(dòng)態(tài)向用戶申請(qǐng)權(quán)限是指在應(yīng)用程序運(yùn)行時(shí)向用戶請(qǐng)求授權(quán)的過程。可以通過調(diào)用requestPermissionsFromUser()方法來實(shí)現(xiàn)。該方法接收一個(gè)權(quán)限列表參數(shù),例如位置、日歷、相機(jī)、麥克風(fēng)等。用戶可以選擇授予權(quán)限或者拒絕授權(quán)。
可以在UIAbility的onWindowStageCreate()回調(diào)中調(diào)用requestPermissionsFromUser()方法來動(dòng)態(tài)申請(qǐng)權(quán)限,也可以根據(jù)業(yè)務(wù)需要在UI中向用戶申請(qǐng)授權(quán)
- checkAccessToken
checkAccessToken()校驗(yàn)應(yīng)用是否授予權(quán)限。在進(jìn)行權(quán)限申請(qǐng)之前,需要先檢查當(dāng)前應(yīng)用程序是否已經(jīng)被授予了權(quán)限。可以通過調(diào)用checkAccessToken()方法來校驗(yàn)當(dāng)前是否已經(jīng)授權(quán)。如果已經(jīng)授權(quán),則可以直接訪問目標(biāo)操作,否則需要進(jìn)行下一步操作,即向用戶申請(qǐng)授權(quán)。
export default class MainAbility extends UIAbility {
onCreate(want, launchParam) {
logger.info(TAG, 'onCreate')
const that = this
this.context.eventHub.on("getAbilityData", (data) => {
data.context = that.context
data.launchWant = want
})
this.requestPermission()
AppStorage.SetOrCreate('context', this.context)
}
requestPermission = async () => {
let permissionRequestResult = await abilityAccessCtrl.createAtManager().requestPermissionsFromUser(this.context,
[
'ohos.permission.CAMERA',
'ohos.permission.MICROPHONE',
'ohos.permission.READ_MEDIA',
'ohos.permission.WRITE_MEDIA',
'ohos.permission.MEDIA_LOCATION',
'ohos.permission.INTERNET'
]);
// 如果權(quán)限列表中有-1,說明用戶拒絕了授權(quán)
if (permissionRequestResult.authResults[0] === 0) {
// 控制相機(jī)是否打開
AppStorage.SetOrCreate(QRCodeScanConst.HAS_CAMERA_PERMISSION, true)
logger.info('MainAbility permissionRequestResult success')
}
await notificationUtil.enableNotification()
}
...
運(yùn)行測(cè)試效果
可以下載橘子購(gòu)物示例應(yīng)用代碼,使用DevEco Studio編譯構(gòu)建,使用Simulator模擬器或者真實(shí)設(shè)備進(jìn)行運(yùn)行體驗(yàn)。
git init
git config core.sparsecheckout true
echo code/Solutions/Shopping/OrangeShopping/ > .git/info/sparse-checkout
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
git pull origin master
注意事項(xiàng)
如果一些高級(jí)別權(quán)限沒有在UnsgnedReleasedProfileTemplate.json文件內(nèi)進(jìn)行ACL權(quán)限配置,會(huì)報(bào)如下錯(cuò)誤:
[Info]App install path:
D:\XXX\applications_app_samples\code\Solutions\Shopping\OrangeShopping\entry\build\default\outputs\default\entry-default-signed.hap,
queuesize:0, msg:error: failed to install bundle.
code:9568289 error: install failed due to grant request permissions failed.
AppMod finish