✅ 核心目标达成:在 UniApp 离线 Android 工程中,实现 Kiosk 模式功能(禁用锁屏、防退出等)无需通过 JS 调用,应用启动时自动激活。
通过自定义 Application 类继承 DCloudApplication,在应用启动时注册 ActivityLifecycleCallbacks,当主 Activity (PandoraEntry/PandoraEntryActivity) 创建时,自动调用 KioskHelper.disableLockScreen() 和 KioskManager.attach()。
app/src/main/java/com/YuyeTech/HeartRate/
├── MyApplication.java # 自定义 Application,实现自动初始化
└── KioskHelper.java # 锁屏控制辅助类
app/src/main/res/xml/
└── device_admin.xml # Device Admin 策略配置
项目根目录/
├── README_KIOSK_INTEGRATION.md # 集成方案总览
├── KIOSK_SETUP_GUIDE.md # 详细配置指南
├── QUICK_TEST_GUIDE.md # 快速测试指南(无需 Device Owner)
├── PROJECT_STRUCTURE.md # 项目结构说明
├── 快速开始.md # 快速开始指南
└── 集成完成总结.md # 本文件
修改内容:
1. Application 改为 com.YuyeTech.HeartRate.MyApplication
2. 添加 4 个权限:DISABLE_KEYGUARD, SYSTEM_ALERT_WINDOW, RECEIVE_BOOT_COMPLETED, FOREGROUND_SERVICE
3. 添加 KioskDeviceAdminReceiver 声明
4. 添加 BootReceiver 声明
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 生命周期监听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);
}
}
}
关键点:
<!-- 1️⃣ 修改 Application -->
<application
android:name="com.YuyeTech.HeartRate.MyApplication" <!-- ✅ 改这里 -->
...>
<!-- 2️⃣ 添加权限 -->
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 3️⃣ 添加 Device Admin Receiver -->
<receiver
android:name="com.ble.mylockview.admin.KioskDeviceAdminReceiver"
android:permission="android.permission.BIND_DEVICE_ADMIN"
android:exported="true">
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<!-- 4️⃣ 添加开机启动 Receiver -->
<receiver
android:name="com.ble.mylockview.boot.BootReceiver"
android:enabled="true"
android:exported="true"
android:directBootAware="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
┌─────────────────────────────────────────────────────────────┐
│ 应用启动流程 │
└─────────────────────────────────────────────────────────────┘
↓
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 调用,完全在原生层自动处理!
# 编译安装
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 无效(只会提示一次)
# 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 | 本文档 | 了解改动内容 |
文件:myLockView/src/main/java/com/ble/mylockview/admin/KioskManager.java
位置:第 55 行
private static final String ADMIN_PASSWORD = "9527"; // ← 改成你的密码
// MyApplication.java
KioskManager.setDebug(false); // ← 关闭 Debug 模式
adb shell am task lock stopadb shell dpm remove-active-admin ...myLockView - Kiosk 模式核心实现myWIFIView - WiFi 配置(需 JS 调用)开发者无需关心 Kiosk 的启动,只需:
MyApplication.java 中注释掉相关代码KioskManager.java 第 55 行KioskManager.java 第 53-54 行AndroidManifest.xml 中禁用 BootReceiverMyApplication.java 第 29 行adb logcat -v time | grep -E "KioskManager|MyApplication|KioskHelper"
# 退出 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
AndroidManifest.xml 中 Application 是否正确KIOSK_SETUP_GUIDE.md 故障排查章节通过本次集成:
集成时间:2026-01-22
适用版本:UniApp 离线打包 + Android 8.0+
核心价值:🚀 无需 JS 调用,应用启动自动进入 Kiosk 模式!
祝使用愉快! 🎉