Requirement Description
After the location permission is turned off, how to guide users to enable precise location and background location permissions, reduce the operation path, and optimize the user experience?
Background Knowledge
Location Permission Description:
| Scenario | Involved permissions | Remark |
|---|---|---|
| BlurredLocation | ohos.permission.APPROXIMATELY_LOCATION | Accuracy of 5 kilometers |
| Precise location | ohos.permission.LOCATION | The accuracy is meter-level, and needs to be applied for together with ohos.permission.APPROXIMATELY_LOCATION |
| Bacstage location | ohos.permission.LOCATION_IN_BACKGROUND | First obtain the foreground location permission, and then use it with long-term tasks |
There are two important points to note:
- Precise Location: After turning off Precise Location, you cannot request authorization again by calling requestPermissionsFromUser() . You must manually enable it in Settings or request authorization again using requestPermissionOnSetting() .
- Background location: The location authorization pop-up only includes three options: "Don't Allow," "Allow for this Use," and "Allow Only During Use." Therefore, you can't use the requestPermissionsFromUser() API to obtain authorization. Instead, you need to direct the user to the app settings interface to manually grant "Always Allow." You can use startability to redirect to the app settings page to reduce the sense of disconnection.
Implementation Steps
Scenario 1: Enable Precise Location Programmatically
- Check current permission status using
checkAccessTokenSync() - Request permissions via
requestPermissionsFromUser()for initial authorization - If denied without popup display, use
requestPermissionOnSetting()for secondary request - Handle authorization results and guide users accordingly
Scenario 2: Enable Background Location via Settings Redirect
- Use
startAbilityto navigate directly to app settings page - Pre-configure bundle name for targeted settings access
- Reduce user navigation steps through direct deep linking
Scenario 3: Enable System Location Feature
- Check system-level location switch status with
isLocationEnabled() - Use
requestGlobalSwitch()to display system location enablement dialog - Handle switch activation results for complete location functionality
Code Snippet / Configuration
Scenario 1: The code guides the user to turn on "Precise Location".
1.Use the checkAccessTokenSync() API to determine whether ohos.permission.LOCATION is authorized and confirm whether the "Precise Location" switch is turned on for the current app.
checkAccessToken(permission: Permissions): abilityAccessCtrl.GrantStatus {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
let tokenID: number = 0;
try {
let bundleInfo: bundleManager.BundleInfo =
bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
tokenID = appInfo.accessTokenId;
} catch (error) {
const err: BusinessError = error as BusinessError;
hilog.error(0x0000, TAG,
`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
}
let grantStatus = atManager.checkAccessTokenSync(tokenID, permission);
return grantStatus;
}
Get the precise location permission authorization status:
let locationGrantStatus : abilityAccessCtrl.GrantStatus = this.checkAccessToken('ohos.permission.LOCATION');
2.In the requestPermissionsFromUser() authorization request callback, determine whether there is an authorization pop-up window. If this is not the first time the app is requesting authorization and no authorization pop-up window is displayed to the user, the app can call the requestPermissionOnSetting() API to request location authorization from the user a second time.
let atManager = abilityAccessCtrl.createAtManager();
try {
// Apply for precise location authorization
atManager.requestPermissionsFromUser(this.context,
['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'])
.then((data) => {
if (data.authResults[0] === -1 || data.authResults[1] === -1) { // User refuses authorization
if (data.dialogShownResults && (data.dialogShownResults[0] || data.dialogShownResults[1])) { // There is an authorization pop-up window
if (data.authResults[0] === -1) {
// The precise location is denied, and the user is guided to enable permission or exit the scene.
}
} else { // Unauthorized pop-up window
//Use requestPermissionOnSetting() to request location authorization again
}
}
})
.catch((err: BusinessError) => {
hilog.error(0x0000, TAG, `err: ${JSON.stringify(err)}`);
})
} catch (err) {
hilog.error(0x0000, TAG, `catch err->${JSON.stringify(err)}`);
}
3.Use the requestPermissionOnSetting() interface to request "precise location" authorization from the user for the second time.
atManager.requestPermissionOnSetting(this.context, ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'])
.then((data: Array<abilityAccessCtrl.GrantStatus>) => {
// Second application location authorization result
})
.catch((err: BusinessError) => {
console.error(`Failed to requestPermissionOnSetting. Code is ${err.code}, message is ${err.message}`);
});
Scenario 2: The code guides the user to enable "background location".
Use startability to jump to the application , jump to the application settings page and select "Always allow", reducing the operation path:
let wantInfo: Want = {
bundleName: "com.huawei.hmos.settings",
abilityName: "com.huawei.hmos.settings.MainAbility",
uri: 'application_info_entry',
parameters: {
settingsParamBundleName: 'com.huawei.samples.locationService' // Replaced with the current application BundleName
}
}
this.context.startAbility(wantInfo).then(() => {
// ...
}).catch((err: BusinessError) => {
// ...
})
Scenario 3: The code guides the user to enable the "System Location" feature.
Use isLocationEnabled() to check whether the system location feature is currently disabled. If the location feature is disabled, location information cannot be obtained. Call requestGlobalSwitch() to open a semi-modal dialog box to enable the location switch.
let atManager = abilityAccessCtrl.createAtManager();
// Determine whether the current position switch status is on
let isLocationEnabled = geoLocationManager.isLocationEnabled();
let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
if (!isLocationEnabled) {
// Pull up the global switch setting pop-up window
atManager.requestGlobalSwitch(context, abilityAccessCtrl.SwitchType.LOCATION).then((data: boolean) => {
if (data) {
// switch on
} else {
// The switch is not turned on
}
}).catch((err: BusinessError) => {
console.error(`Failed to request global switch. Code is ${err.code}, message is ${err.message}`);
});
} else {
// turn on
}
Limitations or Considerations
This example supports API Version 19 Release and above.
This example supports HarmonyOS 5.1.1 Release SDK and above.
This example requires DevEco Studio 5.1.1 Release and above to compile and run.
Top comments (0)