权限申请与状态说明:弹窗之前先把边界讲清楚
【摘要】 权限页只讲四件事:先声明、再检查、按需申请、展示结果。不要把真实分布式同步、拍照、定位这类业务流程混进权限入门页。 本 Demo 复用项目已经声明的 ohos.permission.DISTRIBUTEDDATASYNC,只演示权限申请和状态反馈,不执行真实同步。 交互预期 点击“检查权限”,页面显示当前权限是否已授权
权限申请与状态说明:弹窗之前先把边界讲清楚
权限页只讲四件事:先声明、再检查、按需申请、展示结果。不要把真实分布式同步、拍照、定位这类业务流程混进权限入门页。
本 Demo 复用项目已经声明的 ohos.permission.DISTRIBUTED_DATASYNC,只演示权限申请和状态反馈,不执行真实同步。
交互预期
- 点击“检查权限”,页面显示当前权限是否已授权。
- 点击“申请权限”,系统可能弹出授权框;页面会显示用户同意、拒绝或请求无效。
- 点击“重置状态”,只清空页面展示,不修改系统授权状态。
- API 抛出
BusinessError时,页面显示code/message。
完整示例代码
import { abilityAccessCtrl, bundleManager, common, PermissionRequestResult, Permissions } from '@kit.AbilityKit'
import { BusinessError } from '@kit.BasicServicesKit'
const ENGINEERING_PERMISSION: Permissions = 'ohos.permission.DISTRIBUTED_DATASYNC'
class PermissionStep {
title: string
desc: string
constructor(title: string, desc: string) {
this.title = title
this.desc = desc
}
}
@Entry
@Component
struct PermissionStateDemo {
@State permissionState: string = '尚未检查'
@State requestState: string = '尚未申请'
@State feedback: string = '本页只演示权限状态和申请结果,不执行真实分布式同步。'
@State resultDetail: string = '等待操作'
private atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
private steps: PermissionStep[] = [
new PermissionStep('先声明', '权限需要先在 module.json5 中声明,运行时只负责申请和展示结果。'),
new PermissionStep('再检查', '检查当前应用 accessTokenId 对应权限是否已授权。'),
new PermissionStep('按需申请', '只有用户触发相关能力时才申请,并把同意、拒绝或无效结果展示出来。')
]
private errorToText(error: BusinessError): string {
return `code=${error.code}, message=${error.message}`
}
private grantStatusText(status: abilityAccessCtrl.GrantStatus): string {
if (status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
return '已授权'
}
return '未授权'
}
private requestResultText(result: number): string {
if (result === 0) {
return '用户已授权'
}
if (result === -1) {
return '用户拒绝授权'
}
if (result === 2) {
return '请求无效'
}
return `未知结果:${result}`
}
private async checkPermission(): Promise<void> {
this.permissionState = '正在检查'
this.feedback = '已点击检查权限'
try {
const bundleInfo: bundleManager.BundleInfo =
await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
const tokenId: number = bundleInfo.appInfo.accessTokenId
const status: abilityAccessCtrl.GrantStatus =
await this.atManager.checkAccessToken(tokenId, ENGINEERING_PERMISSION)
this.permissionState = this.grantStatusText(status)
this.resultDetail = `权限:${ENGINEERING_PERMISSION}\n检查结果:${this.permissionState}`
this.feedback = `检查完成:${this.permissionState}`
} catch (error) {
const businessError = error as BusinessError
this.permissionState = '检查失败'
this.resultDetail = this.errorToText(businessError)
this.feedback = `检查失败:${this.errorToText(businessError)}`
}
}
private async requestPermission(): Promise<void> {
this.requestState = '正在申请'
this.feedback = '已点击申请权限'
try {
const context = getContext(this) as common.UIAbilityContext
const result: PermissionRequestResult =
await this.atManager.requestPermissionsFromUser(context, [ENGINEERING_PERMISSION])
const firstResult: number = result.authResults.length > 0 ? result.authResults[0] : 2
this.requestState = this.requestResultText(firstResult)
this.permissionState = firstResult === 0 ? '已授权' : '未授权'
this.resultDetail = `权限:${result.permissions[0]}\n申请结果:${this.requestState}`
this.feedback = `申请完成:${this.requestState}`
} catch (error) {
const businessError = error as BusinessError
this.requestState = '申请失败'
this.resultDetail = this.errorToText(businessError)
this.feedback = `申请失败:${this.errorToText(businessError)}`
}
}
private resetState(): void {
this.permissionState = '尚未检查'
this.requestState = '尚未申请'
this.resultDetail = '等待操作'
this.feedback = '已重置页面状态。'
}
@Builder
stepCard(index: number) {
Column({ space: 6 }) {
Text(this.steps[index].title)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text(this.steps[index].desc)
.fontSize(13)
.fontColor('#4B5563')
.lineHeight(20)
}
.width('100%')
.padding(14)
.borderRadius(12)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#E5E7EB' })
.alignItems(HorizontalAlign.Start)
}
@Builder
statusPanel() {
Column({ space: 10 }) {
Text('当前权限')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text(ENGINEERING_PERMISSION)
.fontSize(13)
.fontColor('#4B5563')
Text(`检查状态:${this.permissionState}`)
.fontSize(15)
.fontColor('#2563EB')
Text(`申请状态:${this.requestState}`)
.fontSize(15)
.fontColor('#0F766E')
}
.width('100%')
.padding(16)
.borderRadius(14)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#E5E7EB' })
.alignItems(HorizontalAlign.Start)
}
build() {
Scroll() {
Column({ space: 20 }) {
Column({ space: 8 }) {
Text('权限申请与状态说明')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text('权限 Demo 只讲声明、检查、申请和反馈,不把真实业务能力混进来。')
.fontSize(14)
.fontColor('#4B5563')
.lineHeight(22)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
ForEach(this.steps, (item: PermissionStep, index: number) => {
this.stepCard(index)
}, (item: PermissionStep) => item.title)
this.statusPanel()
Row({ space: 10 }) {
Button('检查权限')
.height(48)
.layoutWeight(1)
.fontSize(15)
.backgroundColor('#2563EB')
.onClick(() => {
this.checkPermission()
})
Button('申请权限')
.height(48)
.layoutWeight(1)
.fontSize(15)
.backgroundColor('#0F766E')
.onClick(() => {
this.requestPermission()
})
}
.width('100%')
Button('重置状态')
.height(46)
.width('100%')
.fontSize(15)
.fontColor('#334155')
.backgroundColor('#E5E7EB')
.onClick(() => {
this.resetState()
})
Text(this.feedback)
.width('100%')
.fontSize(14)
.fontColor('#1D4ED8')
.lineHeight(22)
.padding(12)
.backgroundColor('#EFF6FF')
.borderRadius(10)
Text(this.resultDetail)
.width('100%')
.fontSize(13)
.fontColor('#4B5563')
.lineHeight(22)
.padding(16)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#E5E7EB' })
.borderRadius(14)
}
.width('100%')
.padding(24)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('100%')
.backgroundColor('#F8FAFC')
}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)