# Kiosk 模式自动启动 - 集成完成总结 ## 📋 任务完成情况 ✅ **核心目标达成**:在 UniApp 离线 Android 工程中,实现 Kiosk 模式功能(禁用锁屏、防退出等)**无需通过 JS 调用**,应用启动时自动激活。 ## 🎯 实现方案 ### 核心思路 通过自定义 `Application` 类继承 `DCloudApplication`,在应用启动时注册 `ActivityLifecycleCallbacks`,当主 Activity (`PandoraEntry`/`PandoraEntryActivity`) 创建时,自动调用 `KioskHelper.disableLockScreen()` 和 `KioskManager.attach()`。 ### 关键技术点 1. **ActivityLifecycleCallbacks** - 监听所有 Activity 生命周期 2. **DevicePolicyManager** - Device Owner 模式控制锁屏和 LockTask 3. **WindowManager.LayoutParams** - 屏幕常亮、解锁屏幕 4. **自动化流程** - 无需 JS 调用,原生层自动处理 ## 📂 文件修改清单 ### ✅ 新增文件(7 个) #### 1. Java 源文件(2 个) ``` app/src/main/java/com/YuyeTech/HeartRate/ ├── MyApplication.java # 自定义 Application,实现自动初始化 └── KioskHelper.java # 锁屏控制辅助类 ``` #### 2. 资源文件(1 个) ``` app/src/main/res/xml/ └── device_admin.xml # Device Admin 策略配置 ``` #### 3. 文档文件(4 个) ``` 项目根目录/ ├── README_KIOSK_INTEGRATION.md # 集成方案总览 ├── KIOSK_SETUP_GUIDE.md # 详细配置指南 ├── QUICK_TEST_GUIDE.md # 快速测试指南(无需 Device Owner) ├── PROJECT_STRUCTURE.md # 项目结构说明 ├── 快速开始.md # 快速开始指南 └── 集成完成总结.md # 本文件 ``` ### ✏️ 修改文件(1 个) #### app/src/main/AndroidManifest.xml ```xml 修改内容: 1. Application 改为 com.YuyeTech.HeartRate.MyApplication 2. 添加 4 个权限:DISABLE_KEYGUARD, SYSTEM_ALERT_WINDOW, RECEIVE_BOOT_COMPLETED, FOREGROUND_SERVICE 3. 添加 KioskDeviceAdminReceiver 声明 4. 添加 BootReceiver 声明 ``` ## 🔍 核心代码详解 ### 1. MyApplication.java - 自动初始化入口 ```java public class MyApplication extends DCloudApplication { @Override public void onCreate() { super.onCreate(); // 配置 Kiosk LaunchConfig.setLaunchActivity(PandoraEntry.class); KioskManager.setDebug(BuildConfig.DEBUG); // ✅ 核心:注册 Activity 生命周期监听 registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { // 只对主 Activity 进行 Kiosk 绑定 if (activity instanceof io.dcloud.PandoraEntry || activity instanceof io.dcloud.PandoraEntryActivity) { // ✅ 这里实现了"无需 JS 调用" KioskHelper.disableLockScreen(activity); // 禁用锁屏 KioskHelper.keepScreenOn(activity); // 屏幕常亮 KioskManager.attach(activity); // 绑定 Kiosk 管理器 } } @Override public void onActivityResumed(@NonNull Activity activity) { if (activity instanceof io.dcloud.PandoraEntry || activity instanceof io.dcloud.PandoraEntryActivity) { KioskManager.onResume(); } } @Override public void onActivityPaused(@NonNull Activity activity) { if (activity instanceof io.dcloud.PandoraEntry || activity instanceof io.dcloud.PandoraEntryActivity) { KioskManager.onPause(); } } @Override public void onActivityDestroyed(@NonNull Activity activity) { if (activity instanceof io.dcloud.PandoraEntry || activity instanceof io.dcloud.PandoraEntryActivity) { KioskManager.onDestroy(); } } }); } } ``` **关键点**: - 继承 `DCloudApplication` 保持 UniApp 功能 - 在 `onCreate()` 中注册全局 Activity 生命周期监听 - 判断 Activity 类型,只对主 Activity 执行 Kiosk 初始化 - 自动处理所有生命周期回调 ### 2. KioskHelper.java - 锁屏控制工具 ```java public class KioskHelper { /** * 禁用锁屏和解锁屏幕 */ public static void disableLockScreen(Activity activity) { try { // 1️⃣ 解锁屏幕(如果当前是锁定状态) activity.getWindow().addFlags( WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON ); // 2️⃣ 作为 Device Owner 禁用锁屏 DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName adminComponent = new ComponentName( activity, KioskDeviceAdminReceiver.class ); if (dpm != null && dpm.isDeviceOwnerApp(activity.getPackageName())) { // 禁用键盘锁(锁屏) dpm.setKeyguardDisabled(adminComponent, true); Log.d(TAG, "✅ 锁屏已禁用"); } else { Log.w(TAG, "⚠️ 不是 Device Owner,无法禁用锁屏"); } } catch (Exception e) { Log.e(TAG, "禁用锁屏失败", e); } } /** * 保持屏幕常亮 */ public static void keepScreenOn(Activity activity) { try { activity.getWindow().addFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ); Log.d(TAG, "✅ 屏幕保持常亮"); } catch (Exception e) { Log.e(TAG, "设置屏幕常亮失败", e); } } } ``` **关键点**: - 提供静态方法,便于调用 - 分离锁屏禁用和屏幕常亮逻辑 - 兼容 Device Owner 和非 Device Owner 模式 - 详细的日志输出便于调试 ### 3. AndroidManifest.xml - 配置清单 ```xml ...> ``` ## 🔄 执行流程图 ``` ┌─────────────────────────────────────────────────────────────┐ │ 应用启动流程 │ └─────────────────────────────────────────────────────────────┘ ↓ System Boot / User Launch ↓ ┌─────────────────────────────────────────────────────────────┐ │ MyApplication.onCreate() │ │ ├─ LaunchConfig.setLaunchActivity() │ │ ├─ KioskManager.setDebug() │ │ └─ registerActivityLifecycleCallbacks() ← ✅ 关键步骤 │ └─────────────────────────────────────────────────────────────┘ ↓ PandoraEntry.onCreate() ↓ ┌─────────────────────────────────────────────────────────────┐ │ ActivityLifecycleCallbacks.onActivityCreated() │ │ ├─ 判断:是否为 PandoraEntry/PandoraEntryActivity? │ │ └─ 是 ✅ │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 自动执行(无需 JS 调用) │ │ ├─ KioskHelper.disableLockScreen(activity) │ │ │ ├─ 添加 FLAG_DISMISS_KEYGUARD │ │ │ ├─ 添加 FLAG_SHOW_WHEN_LOCKED │ │ │ ├─ 添加 FLAG_TURN_SCREEN_ON │ │ │ └─ dpm.setKeyguardDisabled(true) ← Device Owner 需要 │ │ │ │ │ ├─ KioskHelper.keepScreenOn(activity) │ │ │ └─ 添加 FLAG_KEEP_SCREEN_ON │ │ │ │ │ └─ KioskManager.attach(activity) │ │ ├─ hideSystemUI() (隐藏状态栏、导航栏) │ │ ├─ setupSystemUIListener() (监听系统 UI 变化) │ │ └─ enableLockTask() (启用 LockTask 模式) │ └─────────────────────────────────────────────────────────────┘ ↓ ✅ Kiosk 模式已激活 ``` ## 📊 功能对比表 | 功能项 | 实现方式 | Device Owner 需求 | JS 调用需求 | |--------|---------|------------------|------------| | 自动初始化 | MyApplication | ❌ 否 | ❌ 否 | | 屏幕常亮 | FLAG_KEEP_SCREEN_ON | ❌ 否 | ❌ 否 | | 解锁屏幕 | FLAG_DISMISS_KEYGUARD | ❌ 否 | ❌ 否 | | 禁用锁屏 | setKeyguardDisabled() | ✅ 是 | ❌ 否 | | LockTask 模式 | startLockTask() | ✅ 是 | ❌ 否 | | 全屏沉浸 | SYSTEM_UI_FLAG | ❌ 否 | ❌ 否 | | 拦截按键 | onKeyDown() | ❌ 否 | ❌ 否 | | 五指逃生门 | onTouchEvent() | ❌ 否 | ❌ 否 | | 开机自启动 | BootReceiver | ❌ 否 | ❌ 否 | **核心优势**:✅ 所有功能都无需 JS 调用,完全在原生层自动处理! ## 🎯 测试验证 ### 基础测试(无需 Device Owner) ```bash # 编译安装 gradlew assembleDebug adb install app/build/outputs/apk/debug/app-debug.apk # 查看日志 adb logcat | grep -E "MyApplication|KioskHelper|KioskManager" # 启动应用 adb shell am start -n com.YuyeTech.HeartRate/io.dcloud.PandoraEntry ``` **期望日志**: ``` D MyApplication: Application 初始化 D MyApplication: ✅ 绑定 Kiosk 到: PandoraEntry D KioskHelper: ✅ 屏幕保持常亮 W KioskHelper: ⚠️ 不是 Device Owner,无法禁用锁屏 D KioskManager: ❌ 非 DeviceOwner,Kiosk 无效(只会提示一次) ``` ### 完整测试(需要 Device Owner) ```bash # 1. 恢复出厂设置 # 2. 不登录账号 # 3. 安装应用 gradlew assembleRelease adb install app/build/outputs/apk/release/app-release.apk # 4. 设置 Device Owner adb shell dpm set-device-owner com.YuyeTech.HeartRate/com.ble.mylockview.admin.KioskDeviceAdminReceiver # 5. 验证 adb shell dumpsys device_policy | grep "Device Owner" # 6. 查看日志 adb logcat | grep -E "MyApplication|KioskHelper|KioskManager" ``` **期望日志**: ``` D MyApplication: Application 初始化 D MyApplication: ✅ 绑定 Kiosk 到: PandoraEntry D KioskHelper: ✅ 锁屏已禁用 D KioskHelper: ✅ 屏幕保持常亮 D KioskManager: ✅ LockTask 启用(一次) ``` ## 📚 文档说明 | 文档名称 | 用途 | 适用场景 | |---------|------|---------| | **快速开始.md** | 快速上手指南 | 第一次使用 | | **README_KIOSK_INTEGRATION.md** | 集成方案总览 | 了解整体架构 | | **KIOSK_SETUP_GUIDE.md** | 详细配置指南 | 生产环境部署 | | **QUICK_TEST_GUIDE.md** | 快速测试指南 | 开发环境测试 | | **PROJECT_STRUCTURE.md** | 项目结构说明 | 理解代码组织 | | **集成完成总结.md** | 本文档 | 了解改动内容 | ## 🔒 安全建议 ### 1. 修改默认密码 **文件**:`myLockView/src/main/java/com/ble/mylockview/admin/KioskManager.java` **位置**:第 55 行 ```java private static final String ADMIN_PASSWORD = "9527"; // ← 改成你的密码 ``` ### 2. 生产环境配置 ```java // MyApplication.java KioskManager.setDebug(false); // ← 关闭 Debug 模式 ``` ### 3. 管理员退出方式 - **运维人员**:5 指长按 5 秒 → 输入密码 - **开发人员**:`adb shell am task lock stop` - **应急方案**:`adb shell dpm remove-active-admin ...` ## 🎉 集成完成 ### ✅ 已实现功能 1. ✅ 应用启动时自动禁用锁屏(Device Owner 模式) 2. ✅ 应用启动时自动启用屏幕常亮 3. ✅ 应用启动时自动进入 Kiosk 模式(LockTask) 4. ✅ 全屏沉浸式界面(隐藏状态栏、导航栏) 5. ✅ 拦截 Home、Back 等按键 6. ✅ 五指长按 5 秒 + 密码退出机制 7. ✅ 开机自动启动应用 8. ✅ **无需在 JS 中调用任何代码** ### 📦 依赖的模块 - `myLockView` - Kiosk 模式核心实现 - `myWIFIView` - WiFi 配置(需 JS 调用) - UniApp DCloud 框架 ### 🚀 后续使用 开发者无需关心 Kiosk 的启动,只需: 1. 正常开发 UniApp 功能 2. 需要退出 Kiosk 时:5 指长按 5 秒 + 密码 9527 3. 如需禁用 Kiosk:在 `MyApplication.java` 中注释掉相关代码 ### 🔧 自定义选项 - 修改管理员密码:`KioskManager.java` 第 55 行 - 修改逃生门条件:`KioskManager.java` 第 53-54 行 - 禁用开机启动:`AndroidManifest.xml` 中禁用 `BootReceiver` - 调整 Debug 模式:`MyApplication.java` 第 29 行 ## 📞 技术支持 ### 查看日志 ```bash adb logcat -v time | grep -E "KioskManager|MyApplication|KioskHelper" ``` ### 常用命令 ```bash # 退出 Kiosk adb shell am task lock stop # 强制停止 adb shell am force-stop com.YuyeTech.HeartRate # 移除 Device Owner adb shell dpm remove-active-admin com.YuyeTech.HeartRate/com.ble.mylockview.admin.KioskDeviceAdminReceiver ``` ### 问题排查 1. 检查日志是否有 "✅ 绑定 Kiosk 到: PandoraEntry" 2. 检查 `AndroidManifest.xml` 中 Application 是否正确 3. 检查是否设置为 Device Owner 4. 参考 `KIOSK_SETUP_GUIDE.md` 故障排查章节 --- ## 🎊 总结 通过本次集成: - ✅ 实现了 Kiosk 模式的**零 JS 调用**自动启动 - ✅ 保持了 UniApp 原有功能完整性 - ✅ 提供了完善的文档和测试指南 - ✅ 支持 Debug 和 Release 两种模式 - ✅ 兼容 Device Owner 和非 Device Owner 场景 **集成时间**:2026-01-22 **适用版本**:UniApp 离线打包 + Android 8.0+ **核心价值**:🚀 **无需 JS 调用,应用启动自动进入 Kiosk 模式!** --- **祝使用愉快!** 🎉