本文原创发布在华为开发者社区。
介绍
本示例基于设置应用实现引导用户跳转到系统设置页进行权限,通知的相关设置,包含以下两个场景。
场景一:如果应用首次拒绝了消息通知,应用希望能够引导用户拉起设置应用设置允许通知,用来接收应用内的推送消息;并且在设置完后返回页面可以监听到修改后的状态。
场景二:当用户使用一些需要用户授权的api时(如访问获取联系人信息),若用户首次拒绝授权,则需要引导用户到权限设置页面能够主动进行应用权限的修改。
效果预览
场景一:通知权限设置
场景二:位置权限设置
使用说明
- 进入应用出现申请消息通知权限的弹窗,点击“允许”,再点击“去关闭通知”,跳转到系统设置。
- 点击“获取当前位置”按钮,拒绝后应用底部出现开启权限的弹窗,点击“确认”按钮,跳转到系统设置。
实现思路
场景一
通过startability显式拉起设置应用-通知管理界面,配置相应的want信息,在进入页面时通过Notification.requestEnableNotification()监听应用请求通知使能。核心代码如下,源码参考Index.ets。
- 为Button绑定拉起事件
Button(this.buttonText).onClick(() => {
let context = getContext(this) as common.UIAbilityContext;
JumpToSettings(NavEntryKey.SYSTEMUI_NOTIFICATION, context)
})
.margin(10)
Text(this.message)
.margin(10)
- 在打开页面时获取通知管理中按钮状态,Notification.requestEnableNotification()请求发送通知的许可,第一次调用会弹窗让用户选择。
onPageShow(): void {
let context = getContext(this) as common.UIAbilityContext
notificationManager.requestEnableNotification(context).then(() => {
//已打开通知
this.message = '已允许接收消息推送。';
this.buttonText = '去关闭通知';
}).catch((err: Error) => {
//未打开通知
this.message = '已禁止接收消息推送。';
this.buttonText = '去开启通知';
});
}
场景二
暂无直接跳转权限管理的方式,可通过跳转至应用详情进行用户申请权限的修改。核心代码如下,源码参考Index.ets。
- 为Button绑定获取位置信息事件
Button("获取当前位置").onClick(async () => {
const permissions: Array = [
'ohos.permission.APPROXIMATELY_LOCATION',
'ohos.permission.LOCATION'];
let context: Context = getContext(this) as common.UIAbilityContext;
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
atManager.requestPermissionsFromUser(context, permissions).then((data: PermissionRequestResult) => {
let grantStatus: Array = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 已经授权,可以继续访问目标操作
this.getLocation();
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
this.location = null;
this.dialogControllerConfirm.open();
return;
}
}
}).catch((err: BusinessError) => {
hilog.error(0x0000, 'tag', `Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
}).margin(10)
Text(`当前位置:${this.location?.latitude},${this.location?.longitude}`)
.fontSize(16)
.margin(10)
- 调用 getCurrentLocation获取位置信息
getLocation() {
let requestInfo: geoLocationManager.CurrentLocationRequest = {
'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
'scenario': geoLocationManager.LocationRequestScenario.UNSET,
'maxAccuracy': 0
};
let locationChange = (err: BusinessError, location: geoLocationManager.Location): void => {
if (err) {
hilog.error(0x0000, 'tag', `locationChanger: err= ${err}`);
}
if (location) {
this.location = location
}
};
try {
geoLocationManager.getCurrentLocation(requestInfo, locationChange);
} catch (err) {
hilog.error(0x0000, 'tag', `errCode:${err}`);
}
}
- 拒绝授权后的引导弹窗
dialogControllerConfirm: CustomDialogController = new CustomDialogController({
builder: AlertDialog({
content: '已拒绝访问系统位置,是否前往开启?',
primaryButton: {
value: '取消',
action: () => {
},
},
secondaryButton: {
value: '确认',
fontColor: $r('sys.color.ohos_id_color_warning'),
action: () => {
this.openAppInfo();
}
},
}),
autoCancel: true,
customStyle: true,
alignment: DialogAlignment.Bottom
});
- 进入设置-应用详情页
openAppInfo() {
let context = getContext(this) as common.UIAbilityContext;
JumpToSettings(NavEntryKey.APPLICATION_INFO_ENTRY, context)
};
- 跳转设置公共类
export function JumpToSettings(pageName: NavEntryKey, context: common.UIAbilityContext) {
let want: Want = {
bundleName: 'com.huawei.hmos.settings',
abilityName: 'com.huawei.hmos.settings.MainAbility',
uri: pageName,
parameters: {
pushParams: {
bundleName: context.abilityInfo.bundleName // 应用包名
}
// pushParams: context.abilityInfo.bundleName
}
};
if (pageName === 'application_info_entry' && want.parameters) {
want.parameters.pushParams = context.abilityInfo.bundleName
}
context.startAbility(want);
}