1# Requesting User Authorization 2 3<!--Kit: Ability Kit--> 4<!--Subsystem: Security--> 5<!--Owner: @xia-bubai--> 6<!--SE: @linshuqing; @hehehe-li--> 7<!--TSE: @leiyuqian--> 8 9User authorization is required when an application needs to access user privacy information (such as Location or Calendar information) or using system abilities (such as the camera ability to take photos or record videos). The permissions that must be authorized by users are user_grant permissions. 10 11The procedure for requesting user_grant permissions is as follows: 12 131. Declare the permissions required by your application in the configuration file. 14 152. Associate each object that requires a user_grant permission with the related permission. This lets the user know what operations need user authorization. 16 For details about the preceding two steps, see [Declaring Permissions](declare-permissions.md). 17 183. Trigger user authorization via an API when the application in running needs to access the target object. The API first checks whether the user has granted the permission required. If no, a dialog box will be displayed to request authorization from the user. 19 204. Check the user authorization result, and allow the next step only after the user has granted the permission to the application. 21 22This topic elaborates steps 3 and 4. 23 24## Constraints 25 26- For a user_grant permission, show a rationale to the user in a UI element, clearly explaining why your application needs the permission. Based on the rationale, the user then determines whether to grant the permission. 27 28- Frequent pop-up windows may disturb user experience and are not recommended. If a user rejects the authorization, the window for requesting user authorization will not be displayed again. The application needs to provide information to guide the user to manually grant the permission in **Settings**. 29 30- The system permission pop-up window cannot be obscured. 31 32 The system permission pop-up window cannot be obscured by other components. The information in the pop-up window must be completely displayed so that the user can identify and complete authorization. 33 If the system permission pop-up window is displayed in the same position as another component, the system permission pop-up window takes precedence over the other component by default. 34 35- A check for the required permission is mandatory each time before the operation that requires the permission is performed. 36 37 You can use [checkAccessToken()](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#checkaccesstoken9) to check whether the user has granted specific permissions to your application. This API returns [PERMISSION_GRANTED](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#grantstatus) or [PERMISSION_DENIED](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#grantstatus). For details, see the example given below. 38 39- Each time before an API that requires a user_grant permission is called, use [requestPermissionsFromUser()](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9) to check whether the user has already granted the permission. 40 41 After a permission is granted, the user may revoke the permission in **Settings**. Therefore, the previous authorization status cannot be persistent. 42 43- When requesting permissions using **onWindowStageCreate()**, the application needs to wait until the **loadContent()** or **setUIContent()** API is complete or call [requestPermissionsFromUser()](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9) in **loadContent()** or **setUIContent()**. Otherwise, **requestPermissionsFromUser()** will fail before **Content** is loaded. 44 <!--RP1--><!--RP1End--> 45 46## How to Develop 47 48The following example steps you through on how to request the location permissions. 49 50**Figure 1** Requesting the location permissions 51 52<!--RP4--> 53 54<!--RP4End--> 55 561. Request the ohos.permission.LOCATION and ohos.permission.APPROXIMATELY_LOCATION permissions. For details, see [Declaring Permissions](declare-permissions.md). 57 582. Check whether the user has granted the permissions. 59 60 Call [checkAccessToken()](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#checkaccesstoken9) to check whether the user has already granted the permissions that your application requires. If yes, the application can perform subsequent operations. Otherwise, user authorization is required. 61 62 ```ts 63 import { abilityAccessCtrl, bundleManager, Permissions } from '@kit.AbilityKit'; 64 import { BusinessError } from '@kit.BasicServicesKit'; 65 66 async function checkPermissionGrant(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> { 67 let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); 68 let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED; 69 70 // Obtain accessTokenID of the application. 71 let tokenId: number = 0; 72 try { 73 let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); 74 let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo; 75 tokenId = appInfo.accessTokenId; 76 } catch (error) { 77 const err: BusinessError = error as BusinessError; 78 console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`); 79 } 80 81 // Check whether the user has granted the permission. 82 try { 83 grantStatus = await atManager.checkAccessToken(tokenId, permission); 84 } catch (error) { 85 const err: BusinessError = error as BusinessError; 86 console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`); 87 } 88 89 return grantStatus; 90 } 91 92 async function checkPermissions(): Promise<void> { 93 let grantStatus1: boolean = await checkPermissionGrant('ohos.permission.LOCATION') === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;// Obtain the status of the ohos.permission.LOCATION permission. 94 let grantStatus2: boolean = await checkPermissionGrant('ohos.permission.APPROXIMATELY_LOCATION') === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;// Obtain the status of the ohos.permission.APPROXIMATELY_LOCATION permission. 95 // The ohos.permission.LOCATION permission must be requested with the ohos.permission.APPROXIMATELY_LOCATION permission together or after the ohos.permission.APPROXIMATELY_LOCATION permission is available. 96 if (grantStatus2 && !grantStatus1) { 97 // Request the ohos.permission.LOCATION permission. 98 } else if (!grantStatus1 && !grantStatus2) { 99 // Request the ohos.permission.LOCATION and ohos.permission.APPROXIMATELY_LOCATION permissions, or request the ohos.permission.APPROXIMATELY_LOCATION permission. 100 } else { 101 // If the user grants the permission, the application can access the target. 102 } 103 } 104 ``` 105 1063. Request user authorization when your application needs to access location information. 107 108 Call [requestPermissionsFromUser()](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9) to request user authorization. You can specify a list of permissions, such as the permission to access the location, Calendar, camera, or microphone, in the **Array\<Permissions>** parameter of this API. The user can grant or deny the permissions. 109 110 You can have [requestPermissionsFromUser()](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9) called in **onWindowStageCreate()** of the UIAbility to dynamically request user authorization, or request user authorization on the UI based on service requirements. 111 112 When requesting permissions using **onWindowStageCreate()**, the application needs to wait until the **loadContent()** or **setUIContent()** API is complete or call [requestPermissionsFromUser()](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9) in **loadContent()** or **setUIContent()**. Otherwise, **requestPermissionsFromUser()** will fail before **Content** is loaded. 113 114 <!--RP1--><!--RP1End--> 115 116 <!--RP2--> 117 - Sample code for requesting user authorization using UIAbility 118 119 ```ts 120 import { abilityAccessCtrl, common, Permissions, UIAbility } from '@kit.AbilityKit'; 121 import { window } from '@kit.ArkUI'; 122 import { BusinessError } from '@kit.BasicServicesKit'; 123 124 const permissions: Array<Permissions> = ['ohos.permission.LOCATION','ohos.permission.APPROXIMATELY_LOCATION']; 125 function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void { 126 let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); 127 // Determine whether to display a user authorization dialog box based on the return value of requestPermissionsFromUser. 128 atManager.requestPermissionsFromUser(context, permissions).then((data) => { 129 let grantStatus: Array<number> = data.authResults; 130 let length: number = grantStatus.length; 131 for (let i = 0; i < length; i++) { 132 if (grantStatus[i] === 0) { 133 // If the user grants the permission, the application can access the target. 134 } else { 135 // If the user denies the permission, display a message indicating that user authorization is required, and direct the user to set the permission in Settings. 136 return; 137 } 138 } 139 // Authorization is successful. 140 }).catch((err: BusinessError) => { 141 console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`); 142 }) 143 } 144 export default class EntryAbility extends UIAbility { 145 onWindowStageCreate(windowStage: window.WindowStage): void { 146 // ... 147 windowStage.loadContent('pages/Index', (err, data) => { 148 reqPermissionsFromUser(permissions, this.context); 149 // ... 150 }); 151 } 152 153 // ... 154 } 155 ``` 156 157 - Sample code for requesting user authorization on the UI 158 159 ```ts 160 import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit'; 161 import { BusinessError } from '@kit.BasicServicesKit'; 162 163 const permissions: Array<Permissions> = ['ohos.permission.LOCATION','ohos.permission.APPROXIMATELY_LOCATION']; 164 function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void { 165 let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); 166 // Determine whether to display a user authorization dialog box based on the return value of requestPermissionsFromUser. 167 atManager.requestPermissionsFromUser(context, permissions).then((data) => { 168 let grantStatus: Array<number> = data.authResults; 169 let length: number = grantStatus.length; 170 for (let i = 0; i < length; i++) { 171 if (grantStatus[i] === 0) { 172 // If the user grants the permission, the application can access the target. 173 } else { 174 // If the user denies the permission, display a message indicating that user authorization is required, and direct the user to set the permission in Settings. 175 return; 176 } 177 } 178 // Authorization is successful. 179 }).catch((err: BusinessError) => { 180 console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`); 181 }) 182 } 183 184 @Entry 185 @Component 186 struct Index { 187 aboutToAppear() { 188 const context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; 189 reqPermissionsFromUser(permissions, context); 190 } 191 192 build() { 193 // ... 194 } 195 } 196 ``` 197 <!--RP2End--> 198 1994. Perform subsequent operations based on the authorization result. 200 201 After [requestPermissionsFromUser()](../../reference/apis-ability-kit/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9) is called, the application waits for the user authorization result. If the user grants the permission, the application can perform the subsequent operation. Otherwise, display a message indicating that user authorization is required, and direct the user to set the permission on the **Settings** page.<!--RP3--> 202 203 Path: **Settings**\> **Privacy**\> **Permission manager**\> **Apps**\> Target app<!--RP3End--> 204