鸿蒙学习实战之路-STG系列(3/11)-用户授权管理详解
朋友们,前两篇我们介绍了 Screen Time Guard Kit 的基本概念和开发准备工作。今天这篇我们就来学习如何进行用户授权管理,包括请求用户授权、取消用户授权、以及监听用户授权状态变化 o(╯□╰)o
用户授权是使用 Screen Time Guard Kit 的前提,就像去游乐场玩要先买门票一样。没有授权,你的应用就用不了任何管控功能~
今天这篇,我会手把手带你实现用户授权管理的完整功能,全程不超过5分钟(不含你测试的时间)~
一、为什么需要用户授权?
Screen Time Guard Kit 涉及到对用户设备的时间管理和应用限制,属于非常敏感的功能。想象一下,如果随便一个应用就能控制你的手机使用时间,那岂不是太可怕了 o(╯□╰)o
所以,华为要求必须经过用户明确授权才能使用这个 Kit:
- 保护用户隐私 - 用户需要知道哪些应用在控制自己的设备
- 防止滥用 - 避免恶意应用随意控制用户设备
- 用户掌控 - 用户可以随时取消授权,夺回控制权
🥦 西兰花小贴士 :
用户授权就像"家长同意书",应用必须拿到用户的同意才能进行管控操作~
二、用户授权状态
用户授权有三种状态:
| 状态 | 说明 | 能否使用管控功能 |
|---|---|---|
| 已授权(AUTHORIZED) | 用户已授权应用使用 Screen Time Guard Kit | 可以使用 |
| 未授权(UNAUTHORIZED) | 用户未授权应用使用 Screen Time Guard Kit | 不能使用 |
| 未知(UNKNOWN) | 授权状态未知,可能是首次使用 | 需要请求授权 |
🥦 西兰花警告 :
如果用户取消授权,应用将无法继续使用任何管控功能,调用相关接口会报错~
三、请求用户授权
请求用户授权是第一步,就像去游乐场要先买门票一样。
1. 业务流程
请求用户授权的流程就像这样:
应用调用请求授权接口
↓
系统查询本地数据库中的授权状态
↓
如果已授权 → 直接返回
如果未授权 → 弹出授权对话框
↓
用户选择:
- 同意授权 → 授权成功,可以使用了
- 拒绝授权 → 抛出错误码,无法使用
2. 核心接口
请求用户授权主要涉及两个接口:
| 接口名 | 说明 |
|---|---|
requestUserAuth(context) |
请求用户授权,默认策略启动后应用不可卸载 |
requestUserAuth(context, appConfig) |
请求用户授权,可配置策略启动后应用是否可卸载 |
getUserAuthStatus() |
获取当前授权状态 |
3. 开发步骤
步骤 1: 导入相关模块
typescript
import { guardService } from '@kit.ScreenTimeGuardKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
步骤 2: 请求用户授权
typescript
@Entry
@Component
struct AuthPage {
@State authStatus: string = '未知';
build() {
Column() {
Text('用户授权状态: ' + this.authStatus)
.fontSize(18)
.margin({ top: 20 })
Button('请求用户授权')
.onClick(async () => {
try {
await guardService.requestUserAuth(
this.getUIContext().getHostContext() as common.UIAbilityContext
);
this.authStatus = '已授权';
hilog.info(0x0000, 'ScreenTimeGuard', 'requestUserAuth succeeded');
} catch (err) {
const message = (err as BusinessError).message;
const code = (err as BusinessError).code;
this.authStatus = '授权失败: ' + message;
hilog.error(0x0000, 'ScreenTimeGuard',
`requestUserAuth failed with error code: ${code}, message: ${message}`);
}
})
.margin({ top: 20 })
Button('获取授权状态')
.onClick(async () => {
try {
const status = await guardService.getUserAuthStatus();
this.authStatus = status === guardService.AuthStatus.AUTHORIZED ? '已授权' : '未授权';
hilog.info(0x0000, 'ScreenTimeGuard', `user auth status: ${status}`);
} catch (err) {
const message = (err as BusinessError).message;
const code = (err as BusinessError).code;
hilog.error(0x0000, 'ScreenTimeGuard',
`getUserAuthStatus failed with error code: ${code}, message: ${message}`);
}
})
.margin({ top: 10 })
}
.width('100%')
.height('100%')
.padding(20)
}
}
🥦 西兰花小贴士 :
首次调用 requestUserAuth 时,系统会弹出授权对话框。用户同意后,再次调用就不会再弹出了~
步骤 3: 配置应用是否可卸载
如果你想配置策略启动后应用是否可卸载,可以这样:
typescript
// 策略启动后应用不可卸载(默认)
await guardService.requestUserAuth(
this.getUIContext().getHostContext() as common.UIAbilityContext,
{ allowUninstall: false }
);
// 策略启动后应用可卸载
await guardService.requestUserAuth(
this.getUIContext().getHostContext() as common.UIAbilityContext,
{ allowUninstall: true }
);
🥦 西兰花警告 :
如果设置 allowUninstall: false,策略启动后应用将无法卸载,这是为了防止用户绕过管控。这个限制也合理吧? (┓( ´∀` )┏
四、取消用户授权
取消用户授权就像退票,用户可以随时取消对应用的授权。
1. 业务流程
取消用户授权的流程就像这样:
应用调用取消授权接口
↓
系统查询本地数据库中的授权状态
↓
如果已授权 → 修改为未授权状态,返回成功
如果未授权 → 直接返回成功
2. 核心接口
取消用户授权主要涉及两个接口:
| 接口名 | 说明 |
|---|---|
revokeUserAuth() |
取消用户授权 |
getUserAuthStatus() |
获取当前授权状态 |
3. 开发步骤
typescript
@Entry
@Component
struct RevokeAuthPage {
@State authStatus: string = '未知';
build() {
Column() {
Text('用户授权状态: ' + this.authStatus)
.fontSize(18)
.margin({ top: 20 })
Button('取消用户授权')
.onClick(async () => {
try {
await guardService.revokeUserAuth();
this.authStatus = '未授权';
hilog.info(0x0000, 'ScreenTimeGuard', 'revokeUserAuth succeeded');
} catch (err) {
const message = (err as BusinessError).message;
const code = (err as BusinessError).code;
hilog.error(0x0000, 'ScreenTimeGuard',
`revokeUserAuth failed with error code: ${code}, message: ${message}`);
}
})
.margin({ top: 20 })
Button('获取授权状态')
.onClick(async () => {
try {
const status = await guardService.getUserAuthStatus();
this.authStatus = status === guardService.AuthStatus.AUTHORIZED ? '已授权' : '未授权';
hilog.info(0x0000, 'ScreenTimeGuard', `user auth status: ${status}`);
} catch (err) {
const message = (err as BusinessError).message;
const code = (err as BusinessError).code;
hilog.error(0x0000, 'ScreenTimeGuard',
`getUserAuthStatus failed with error code: ${code}, message: ${message}`);
}
})
.margin({ top: 10 })
}
.width('100%')
.height('100%')
.padding(20)
}
}
🥦 西兰花小贴士 :
取消授权后,应用将无法继续使用任何管控功能。如果用户想再次使用,需要重新请求授权~
五、监听授权状态变化
用户不仅可以通过你的应用管理授权,还可以通过系统的"健康使用设备"页面管理授权。当用户在系统页面中开启或关闭授权时,你的应用可以通过回调监听到这个变化。
1. 业务流程
监听授权状态变化的流程就像这样:
用户在"健康使用设备"页面中操作授权开关
↓
系统拉起应用的 TimeGuardExtensionAbility 进程
↓
执行对应的回调方法:
- 开启授权 → onUserAuthSwitchOn
- 关闭授权 → onUserAuthSwitchOff
↓
应用可以在回调中执行特定逻辑
🥦 西兰花警告 :
只有用户在"健康使用设备"页面操作授权开关时才会触发回调,应用调用 requestUserAuth 或 revokeUserAuth 不会触发~
2. 核心接口
监听授权状态变化主要涉及两个回调方法:
| 方法名 | 说明 |
|---|---|
onUserAuthSwitchOn() |
用户开启授权时触发 |
onUserAuthSwitchOff() |
用户关闭授权时触发 |
3. 开发步骤
步骤 1: 导入相关模块
typescript
import { TimeGuardExtensionAbility } from '@kit.ScreenTimeGuardKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
步骤 2: 创建 TimeGuardExtensionAbility
创建一个继承 TimeGuardExtensionAbility 的类,重写回调方法:
typescript
// ets/entryability/TimeGuardExtension.ets
export default class TimeGuardExtension extends TimeGuardExtensionAbility {
async onUserAuthSwitchOn(): Promise<void> {
hilog.info(0x0000, 'TimeGuardExtension', '用户开启了授权');
// 在这里执行用户开启授权时的逻辑
// 比如清除所有策略、更新UI状态等
}
async onUserAuthSwitchOff(): Promise<void> {
hilog.info(0x0000, 'TimeGuardExtension', '用户关闭了授权');
// 在这里执行用户关闭授权时的逻辑
// 比如保存当前状态、清理资源等
}
}
步骤 3: 配置 module.json5
在 entry/src/main/module.json5 文件中添加 extensionAbilities 配置:
json5
{
"module": {
"name": "entry",
"type": "entry",
// ... 其他配置
"extensionAbilities": [
{
"name": "TimeGuardExtension",
"type": "screenTimeGuard",
"srcEntry": "./ets/entryability/TimeGuardExtension.ets",
"exported": false,
"skills": [
{
"actions": ["action.ohos.timeGuard.listener"]
}
]
}
]
}
}
🥦 西兰花小贴士 :
TimeGuardExtensionAbility 和你的应用运行在不同进程,但共用沙箱。如果需要传递数据,可以通过用户首选项、数据库或者公共事件来实现~
4. 数据传递示例
由于 TimeGuardExtensionAbility 和应用在不同进程,无法直接传递数据。这里给一个通过用户首选项传递数据的示例:
typescript
// 应用侧 - 保存数据
import { preferences } from '@kit.ArkData';
async function saveAuthStatus(status: string) {
let context = getContext(this) as common.UIAbilityContext;
let pref = await preferences.getPreferences(context, 'auth_data');
await pref.put('auth_status', status);
await pref.flush();
}
// TimeGuardExtensionAbility 侧 - 读取数据
async function getAuthStatus(): Promise<string> {
let pref = await preferences.getPreferences(this.context, 'auth_data');
let status = await pref.get('auth_status', 'unknown') as string;
return status;
}
六、完整示例代码
下面是一个完整的示例,展示了如何实现用户授权管理的完整功能:
typescript
import { guardService } from '@kit.ScreenTimeGuardKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
import { preferences } from '@kit.ArkData';
@Entry
@Component
struct UserAuthDemo {
@State authStatus: string = '未知';
private pref: preferences.Preferences | null = null;
async aboutToAppear() {
// 初始化用户首选项
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
this.pref = await preferences.getPreferences(context, 'auth_data');
// 检查当前授权状态
await this.checkAuthStatus();
}
/**
* 检查授权状态
*/
async checkAuthStatus() {
try {
const status = await guardService.getUserAuthStatus();
this.authStatus = status === guardService.AuthStatus.AUTHORIZED ? '已授权' : '未授权';
hilog.info(0x0000, 'UserAuthDemo', `current auth status: ${status}`);
// 保存到用户首选项
if (this.pref) {
await this.pref.put('auth_status', this.authStatus);
await this.pref.flush();
}
} catch (err) {
const message = (err as BusinessError).message;
const code = (err as BusinessError).code;
hilog.error(0x0000, 'UserAuthDemo',
`checkAuthStatus failed with error code: ${code}, message: ${message}`);
}
}
/**
* 请求用户授权
*/
async requestAuth() {
try {
await guardService.requestUserAuth(
this.getUIContext().getHostContext() as common.UIAbilityContext
);
this.authStatus = '已授权';
hilog.info(0x0000, 'UserAuthDemo', 'requestUserAuth succeeded');
// 保存到用户首选项
if (this.pref) {
await this.pref.put('auth_status', this.authStatus);
await this.pref.flush();
}
} catch (err) {
const message = (err as BusinessError).message;
const code = (err as BusinessError).code;
this.authStatus = '授权失败: ' + message;
hilog.error(0x0000, 'UserAuthDemo',
`requestUserAuth failed with error code: ${code}, message: ${message}`);
}
}
/**
* 取消用户授权
*/
async revokeAuth() {
try {
await guardService.revokeUserAuth();
this.authStatus = '未授权';
hilog.info(0x0000, 'UserAuthDemo', 'revokeUserAuth succeeded');
// 保存到用户首选项
if (this.pref) {
await this.pref.put('auth_status', this.authStatus);
await this.pref.flush();
}
} catch (err) {
const message = (err as BusinessError).message;
const code = (err as BusinessError).code;
hilog.error(0x0000, 'UserAuthDemo',
`revokeUserAuth failed with error code: ${code}, message: ${message}`);
}
}
build() {
Column() {
Text('用户授权管理演示')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 40 })
Text('当前授权状态: ' + this.authStatus)
.fontSize(18)
.margin({ top: 30 })
.fontColor(
this.authStatus === '已授权' ? '#00FF00' :
this.authStatus === '未授权' ? '#FF0000' : '#000000'
)
Button('请求用户授权')
.onClick(() => this.requestAuth())
.margin({ top: 30 })
.width('80%')
Button('取消用户授权')
.onClick(() => this.revokeAuth())
.margin({ top: 10 })
.width('80%')
Button('刷新授权状态')
.onClick(() => this.checkAuthStatus())
.margin({ top: 10 })
.width('80%')
}
.width('100%')
.height('100%')
.padding(20)
}
}
七、注意事项
🥦 西兰花警告:
- 必须先请求授权: 使用任何管控功能之前,必须先请求用户授权,否则会报错
- 授权对话框只弹出一次 : 首次调用
requestUserAuth时才会弹出,之后不会再弹 - 取消授权后无法继续使用: 取消授权后,应用将无法继续使用任何管控功能
- 回调只在系统页面操作时触发: 只有用户在"健康使用设备"页面操作授权开关时才会触发回调
- 进程隔离 :
TimeGuardExtensionAbility和应用在不同进程,无法直接传递数据 - 密码保护: 如果用户设置了健康使用设备密码,取消授权时需要输入密码
八、文档资源
官方文档链接:
九、总结
用户授权管理是使用 Screen Time Guard Kit 的前提,必须先获得用户授权才能使用任何管控功能。
核心要点:
- 必须先请求用户授权才能使用管控功能
- 用户可以随时取消授权
- 可以通过回调监听用户在系统页面的授权状态变化
TimeGuardExtensionAbility和应用在不同进程,需要通过其他方式传递数据- 取消授权后应用将无法继续使用管控功能
用户授权管理就像"买票入园",没有票就进不去游乐场 o(╯□╰)o
下一步行动
建议你:
- 先实现基本的请求授权和取消授权功能
- 添加授权状态查询功能
- 实现
TimeGuardExtensionAbility监听授权状态变化 - 测试各种授权场景,确保功能正常
- 在应用启动时检查授权状态,引导用户授权
记住,不教理论,只给你能跑的代码和避坑指南! _
我是盐焗西兰花,
不教理论,只给你能跑的代码和避坑指南。
下期见!🥦