| | |
| | | import NotificationManager from "android.app.NotificationManager"; |
| | | import Notification from "android.app.Notification"; |
| | | import PendingIntent from "android.app.PendingIntent"; |
| | | import Service from "android.app.Service"; |
| | | import IBinder from "android.os.IBinder"; |
| | | import PowerManager from "android.os.PowerManager"; |
| | | import BatteryManager from "android.os.BatteryManager"; |
| | | import { UTSAndroid } from "io.dcloud.uts"; |
| | |
| | | // 保活服务是否已启动的标志 |
| | | let isKeepAliveRunning = false; |
| | | |
| | | // WakeLock 引用,用于保持 CPU 运行 |
| | | let wakeLock: PowerManager.WakeLock | null = null; |
| | | |
| | | /** |
| | | * 启动应用保活 |
| | | * 通过启动前台服务来保持应用在后台运行 |
| | | * 通过 WakeLock + 通知来保持应用在后台运行 |
| | | */ |
| | | export function keepAliveStart(): void { |
| | | const context = UTSAndroid.getAppContext(); |
| | |
| | | } |
| | | |
| | | try { |
| | | // 创建通知渠道 (Android 8.0+) |
| | | // 1. 获取 WakeLock 唤醒锁,保持 CPU 运行 |
| | | acquireWakeLock(context); |
| | | |
| | | // 2. 创建通知渠道 (Android 8.0+) |
| | | createNotificationChannel(context); |
| | | |
| | | // 创建并显示前台通知 |
| | | // 3. 创建并显示前台通知 |
| | | showForegroundNotification(context); |
| | | |
| | | // 4. 注册应用生命周期监听 |
| | | registerLifecycleCallbacks(); |
| | | |
| | | isKeepAliveRunning = true; |
| | | console.log("keepAliveStart: 保活服务启动成功"); |
| | | console.log("keepAliveStart: 保活服务启动成功(WakeLock已获取)"); |
| | | } catch (e) { |
| | | console.error("keepAliveStart: 启动失败", e); |
| | | } |
| | |
| | | } |
| | | |
| | | try { |
| | | // 释放 WakeLock |
| | | releaseWakeLock(); |
| | | |
| | | // 取消通知 |
| | | const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager; |
| | | notificationManager.cancel(NOTIFICATION_ID); |
| | | |
| | | isKeepAliveRunning = false; |
| | | console.log("keepAliveStop: 保活服务已停止"); |
| | | console.log("keepAliveStop: 保活服务已停止(WakeLock已释放)"); |
| | | } catch (e) { |
| | | console.error("keepAliveStop: 停止失败", e); |
| | | } |
| | |
| | | const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager; |
| | | notificationManager.notify(NOTIFICATION_ID, notification); |
| | | } |
| | | |
| | | /** |
| | | * 获取 WakeLock 唤醒锁 |
| | | * PARTIAL_WAKE_LOCK: 保持 CPU 运行,屏幕和键盘背光可以关闭 |
| | | */ |
| | | function acquireWakeLock(context: Context): void { |
| | | if (wakeLock != null && wakeLock!.isHeld()) { |
| | | console.log("acquireWakeLock: WakeLock 已持有"); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | const powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager; |
| | | // PARTIAL_WAKE_LOCK 保持 CPU 运行 |
| | | wakeLock = powerManager.newWakeLock( |
| | | PowerManager.PARTIAL_WAKE_LOCK, |
| | | "KeepAlive::WakeLock" |
| | | ); |
| | | |
| | | if (wakeLock != null) { |
| | | // 设置超时时间为无限(传 0 或负数表示无限) |
| | | // 使用 acquire() 无参版本 |
| | | wakeLock!.setReferenceCounted(false); |
| | | wakeLock!.acquire(); |
| | | console.log("acquireWakeLock: WakeLock 获取成功"); |
| | | } |
| | | } catch (e) { |
| | | console.error("acquireWakeLock: WakeLock 获取失败", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 释放 WakeLock 唤醒锁 |
| | | */ |
| | | function releaseWakeLock(): void { |
| | | if (wakeLock != null && wakeLock!.isHeld()) { |
| | | try { |
| | | wakeLock!.release(); |
| | | wakeLock = null; |
| | | console.log("releaseWakeLock: WakeLock 已释放"); |
| | | } catch (e) { |
| | | console.error("releaseWakeLock: WakeLock 释放失败", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 注册应用生命周期回调 |
| | | * 当应用进入后台时,确保 WakeLock 保持持有 |
| | | */ |
| | | function registerLifecycleCallbacks(): void { |
| | | // 应用进入后台时的回调 |
| | | UTSAndroid.onAppActivityPause(() => { |
| | | console.log("onAppActivityPause: 应用进入后台"); |
| | | // 确保 WakeLock 仍然持有 |
| | | const context = UTSAndroid.getAppContext(); |
| | | if (context != null && isKeepAliveRunning) { |
| | | if (wakeLock == null || !wakeLock!.isHeld()) { |
| | | acquireWakeLock(context); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // 应用返回前台时的回调 |
| | | UTSAndroid.onAppActivityResume(() => { |
| | | console.log("onAppActivityResume: 应用返回前台"); |
| | | }); |
| | | |
| | | // 应用被销毁时的回调 |
| | | UTSAndroid.onAppActivityDestroy(() => { |
| | | console.log("onAppActivityDestroy: 应用被销毁"); |
| | | // 释放资源 |
| | | releaseWakeLock(); |
| | | isKeepAliveRunning = false; |
| | | }); |
| | | |
| | | console.log("registerLifecycleCallbacks: 生命周期回调已注册"); |
| | | } |