鸿蒙7新特性实战⑧:商用Kiosk锁定应用完整开发流程(API26 自助终端/门店一体机)

前言
Kiosk(商用自助锁定模式)是鸿蒙面向门店收银机、自助取票机、政务终端、广告一体机的企业级管控能力,核心作用:
设备开机后仅运行当前应用,屏蔽返回键、Home桌面、下拉通知栏、多任务、分屏、设置入口,用户无法退出应用、切换其他程序,防止客户误操作系统。
API26(鸿蒙7)kioskManager 统一收敛至 @kit.AbilityKit,属于企业受限系统权限,普通个人应用无法使用,必须企业开发者认证+AGC申请受控权限Profile。
一、核心前置门槛(开发前必须完成,否则API直接报错)
1.1 账号资质要求
- 华为开发者联盟企业实名认证,个人账号无权限申请Kiosk管控权限;
- 设备为鸿蒙企业版/商用自助终端(普通消费手机仅调试,无法正式商用锁机);
- 应用归属企业商用场景(自助终端、政务、零售门店),上架审核需提供商用场景说明材料。
1.2 关键受限权限说明
核心权限:ohos.permission.ENTERPRISE_SET_KIOSK
- 权限等级:system_grant 系统受控权限,不能动态弹窗申请;
- 获取方式:AGC创建发布Profile时勾选该权限,审核通过后下载签名Profile打包;
- 作用:允许应用进入/退出Kiosk单应用锁定模式、查询锁机状态。
1.3 完整前置流程(四步)
- 企业账号完成认证;
- AGC创建应用,申请发布Profile,勾选
ENTERPRISE_SET_KIOSK并提交商用场景说明; - 下载带权限的签名p7b Profile、证书;
- 工程配置正式企业签名,调试/打包均使用该签名,自动签名无受控权限无法调用Kiosk API。
二、工程配置全量代码
2.1 module.json5 权限、窗口、自启配置
{
"module": {
"name": "entry",
"type": "har",
"deviceTypes": ["tablet", "phone"],
"requestPermissions": [
{
"name": "ohos.permission.ENTERPRISE_SET_KIOSK",
"reason": "$string:kiosk_lock_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
},
// 全屏、窗口管控配套权限
{
"name": "ohos.permission.WINDOW_FULLSCREEN",
"reason": "$string:fullscreen_reason",
"usedScene": { "abilities": ["EntryAbility"], "when": "always" }
}
],
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"exported": true,
"launchType": "singleTask",
"skills": [],
"metadata": [
// 开机自启动(商用终端必备)
{
"name": "ohos.ability.startup",
"value": "auto_start"
}
],
"window": {
"designWidth": 720,
"autoHiddenNavigationBar": true,
"autoHiddenStatusBar": true
}
}
]
}
}
2.2 oh-package.json5 标准@kit导入依赖
"dependencies": {
"@kit.AbilityKit": "1.0.0",
"@kit.ArkUI": "1.0.0",
"@kit.PerformanceAnalysisKit": "1.0.0",
"@kit.BasicServicesKit": "1.0.0"
}
三、Kiosk核心API能力总览(@kit.AbilityKit.kioskManager)
| API | 作用 |
|---|---|
enterKioskMode(context) |
进入单应用锁定模式,屏蔽所有系统逃逸入口 |
exitKioskMode(context) |
退出锁机(管理员密码/后台运维使用) |
getKioskStatus() |
查询当前锁机状态:是否锁定、锁定应用包名 |
on("kioskChange", callback) |
监听锁机状态变更(被强制退出、系统切换) |
锁机后系统自动限制效果
- 屏蔽底部虚拟导航栏(返回、主页、多任务键消失);
- 顶部状态栏/通知栏下拉手势拦截,无法调出控制中心;
- Home键、多任务手势失效,无法返回桌面;
- 分屏、悬浮窗、自由窗口全部禁用;
- 其他应用无法前台拉起,系统仅保留当前应用进程;
- 屏蔽系统设置快捷入口、下拉菜单关机/重启选项。
四、完整分层实战代码
4.1 第一层:EntryAbility 生命周期自动进锁+全屏隐藏系统栏
应用切前台自动校验并进入Kiosk,页面加载前设置全屏无系统UI:
import { UIAbility, Want, window, kioskManager, common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = "KioskAbility";
const DOMAIN = 0x0005;
export default class EntryAbility extends UIAbility {
uiContext: common.UIAbilityContext | null = null;
onCreate(want: Want, launchParam: common.LaunchParam): void {
this.uiContext = this.context as common.UIAbilityContext;
hilog.info(DOMAIN, TAG, "商用Kiosk应用启动");
}
// 窗口创建,全屏隐藏状态栏、导航栏
onWindowStageCreate(windowStage: window.WindowStage): void {
const mainWin = windowStage.getMainWindow();
mainWin.then(win => {
// 全屏模式
win.setWindowLayoutFullScreen(true);
// 透明系统栏,彻底隐藏
win.setWindowSystemBarProperties({
statusBarOpacity: 0,
navigationBarOpacity: 0,
statusBarBackgroundColor: "#00000000",
navigationBarBackgroundColor: "#00000000"
});
});
// 加载业务页面
windowStage.loadContent("pages/KioskIndex", (err) => {
if (err.code) hilog.error(DOMAIN, TAG, `页面加载失败:${err.message}`);
});
}
// 切前台自动进入锁机模式(核心)
onForeground(): void {
this.autoEnterKiosk();
}
// 自动校验并进入Kiosk锁定
private async autoEnterKiosk() {
if (!this.uiContext) return;
try {
const status = kioskManager.getKioskStatus();
// 已为本应用锁定,无需重复进入
if (status.isKioskMode && status.kioskBundleName === this.uiContext.bundleName) {
hilog.info(DOMAIN, TAG, "已处于Kiosk锁定模式");
return;
}
// 进入单应用锁定
await kioskManager.enterKioskMode(this.uiContext);
hilog.info(DOMAIN, TAG, "成功进入商用Kiosk锁机模式");
} catch (err) {
const e = err as BusinessError;
// 错误码160001:系统已存在其他Kiosk应用,需先退出原有锁机
if (e.code === 160001) {
hilog.error(DOMAIN, TAG, "当前设备已有其他应用锁定,无法进入");
} else {
hilog.error(DOMAIN, TAG, `进入Kiosk失败 code:${e.code} msg:${e.message}`);
}
}
}
// 监听锁机状态变更回调
onBackground(): void {
kioskManager.off("kioskChange");
}
}
4.2 第二层:业务主页面(管理员退出锁机入口)
普通用户无退出按钮,仅管理员输入密码后调用exitKioskMode退出锁机,支持密码校验、状态实时展示:
import { ComponentV2, Local } from '@kit.ArkUI';
import { kioskManager, common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = "KioskPage";
const ADMIN_PWD = "admin123456"; // 管理员退出密码,生产环境加密存储
@Entry
@ComponentV2
struct KioskIndex {
@Local kioskEnable: boolean = false;
@Local inputPwd: string = "";
@Local tipText: string = "商用自助终端 · 已锁定,仅管理员可退出";
private uiCtx: common.UIAbilityContext | null = null;
aboutToAppear() {
this.uiCtx = getContext(this) as common.UIAbilityContext;
this.refreshKioskStatus();
// 监听锁机状态变化
kioskManager.on("kioskChange", () => {
this.refreshKioskStatus();
});
}
aboutToDisappear() {
kioskManager.off("kioskChange");
}
// 刷新当前锁机状态
private refreshKioskStatus() {
const status = kioskManager.getKioskStatus();
this.kioskEnable = status.isKioskMode;
if (this.kioskEnable) {
this.tipText = `锁定生效,当前应用:${status.kioskBundleName}`;
} else {
this.tipText = "未进入Kiosk锁定模式";
}
}
// 管理员退出锁机模式
private async exitLockMode() {
if (this.inputPwd !== ADMIN_PWD) {
this.tipText = "密码错误,无法退出锁定";
return;
}
if (!this.uiCtx) return;
try {
await kioskManager.exitKioskMode(this.uiCtx);
this.tipText = "已成功退出Kiosk锁机模式";
this.inputPwd = "";
} catch (err) {
const e = err as BusinessError;
this.tipText = `退出失败:${e.message}`;
hilog.error(0x0005, TAG, `退出Kiosk异常:${JSON.stringify(err)}`);
}
}
build() {
Column({ space: 30 }) {
Text("商用自助终端 Kiosk 锁定演示")
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 40 });
Text(this.tipText)
.fontSize(16)
.fontColor(this.kioskEnable ? "#00B42A" : "#F53F3F");
// 业务自助交互区域(客户操作区)
Column() {
Text("客户业务操作区")
.fontSize(20)
Button("业务办理")
.width(200)
.height(50)
.backgroundColor("#0A59F7")
}
.width("90%")
.height(220)
.padding(20)
.backgroundColor("#F5F7FA")
.borderRadius(12);
// 管理员退出区域(隐藏给普通客户,运维使用)
Column({ space: 12 }) {
Text("管理员退出锁机(仅运维)")
.fontSize(14)
.fontColor("#666");
TextInput({ text: this.inputPwd })
.width("90%")
.height(44)
.type(InputType.Password)
.onChange(v => this.inputPwd = v);
Button("验证密码退出锁定")
.width("90%")
.height(48)
.backgroundColor("#F53F3F")
.onClick(() => this.exitLockMode());
}
.width("90%")
.padding(16)
.backgroundColor("#FFFFFF")
.borderRadius(12);
Blank();
Text("💡 锁机后无法下拉通知栏、返回桌面、切换其他应用")
.fontSize(12)
.fontColor("#888888")
.margin({ bottom: 40 });
}
.width("100%")
.height("100%")
.backgroundColor("#F8F9FA");
}
}
五、配套加固方案(多层防逃逸,商用必备)
仅靠Kiosk模式仍存在少量逃逸路径,商用终端需叠加四层防护:
5.1 防护1:开机自启
metadata:ohos.ability.startup:auto_start,设备上电自动拉起应用并进入锁机,无需人工点开。
5.2 防护2:窗口全屏+隐藏系统栏
Ability窗口阶段强制隐藏状态栏、导航栏,无任何系统UI可触发下拉手势。
5.3 防护3:限制应用被后台销毁后自动重启
配置launchType:singleTask,系统内存回收后自动重启Ability,重新进入Kiosk锁机。
5.4 防护4:设备MDM管控(高阶商用)
企业批量终端搭配HEM设备管理平台:
- 禁用USB调试、文件传输;
- 屏蔽设置、应用市场、浏览器;
- 限制物理按键(音量、电源长按);
- 远程下发指令进入/退出Kiosk,无需现场输入密码。
六、调试与打包完整流程
- AGC申请受控Profile:勾选
ohos.permission.ENTERPRISE_SET_KIOSK,提交商用自助终端场景材料,等待审核(1~3工作日); - 配置企业正式签名:DevEco Studio导入下载的p12证书、p7b Profile;
- 真机调试:仅企业商用设备支持,普通消费手机调用API会报权限不足;模拟器无Kiosk系统服务,无法调试;
- 打包Release商用包:Build → Build Hap(s),使用带权限的签名;
- 设备安装验证:安装后启动自动进入锁机,测试下拉通知、返回手势、Home键全部失效。
七、高频踩坑避坑大全
坑1:enterKioskMode 报错 权限不足
- 未使用企业认证账号;
- AGC申请Profile时未勾选
ENTERPRISE_SET_KIOSK; - 使用DevEco自动调试签名,无受控权限;
- module.json5未声明对应权限。
坑2:错误码160001 已存在其他Kiosk应用
一台设备同一时间仅允许一个应用锁定,需先退出原有应用的Kiosk模式,再执行当前应用进入锁机。
坑3:切换分屏/下拉通知栏仍能调出系统UI
- 未在WindowStage设置全屏+透明系统栏;
- 窗口配置未开启
autoHiddenNavigationBar/autoHiddenStatusBar; - 设备非企业商用固件,消费版系统管控能力受限。
坑4:应用后台被杀后,锁机失效
解决方案:
- 配置开机自启;
singleTask单实例启动模式;- onForeground自动执行
autoEnterKiosk,切前台重新上锁。
坑5:普通个人手机无法使用Kiosk API
底层限制:ENTERPRISE_SET_KIOSK仅对企业商用设备、企业MDM应用开放,个人消费手机无系统授权通道。
坑6:退出锁机后系统UI异常(导航栏不恢复)
调用exitKioskMode后,重启窗口重置系统栏属性,或重启应用恢复默认窗口样式。
八、商用生产环境最佳实践
- 密码安全:管理员退出密码禁止硬编码,使用SecureStorage加密存储,支持后台远程修改;
- 日志审计:Kiosk进入/退出、密码验证全部写入系统日志,可追溯运维操作;
- 异常兜底:onForeground自动重新上锁,防止进程异常解锁;
- 分层UI隔离:客户操作区与管理员退出面板视觉隔离,现场隐藏密码输入区域;
- 批量运维:多终端接入HEM MDM平台,远程一键切换锁机状态,无需现场操作;
- 断电保护:开启开机自启,断电重启自动恢复锁定,无人值守稳定运行。
总结
鸿蒙7 Kiosk商用锁定是面向线下自助终端的企业级管控方案,核心依赖kioskManager套件+企业受控权限,实现单应用完全锁定、屏蔽所有系统逃逸入口。
完整落地分为资质申请→工程配置→Ability自动上锁→管理员密码退出→多层加固五步,普通个人应用无法使用,仅企业商用自助设备适配。开发重点做好权限申请、前台自动重锁、窗口全屏隐藏系统栏三层核心逻辑,即可满足门店、政务、零售终端无人值守商用场景。
更多推荐




所有评论(0)