diff --git a/app/src/main/java/com/xiaoqu/watch/device/screen/FiseScreenController.kt b/app/src/main/java/com/xiaoqu/watch/device/screen/FiseScreenController.kt index de55e04..6d6a386 100644 --- a/app/src/main/java/com/xiaoqu/watch/device/screen/FiseScreenController.kt +++ b/app/src/main/java/com/xiaoqu/watch/device/screen/FiseScreenController.kt @@ -10,7 +10,12 @@ import javax.inject.Singleton /** * FISE 定制 ROM 屏幕控制实现 - * 通过系统广播控制亮屏/熄屏(FISE ROM 特有) + * 通过系统广播 + WakeLock 控制亮屏/熄屏 + * + * 亮屏使用双重机制: + * 1. ACQUIRE_CAUSES_WAKEUP WakeLock — 强制唤醒屏幕硬件(Android 标准方式) + * 2. FISE ROM 广播 — 确保 ROM 层面也同步 + * 仅靠 FISE 广播在屏幕休眠时无法唤醒(实测验证) */ @Singleton class FiseScreenController @Inject constructor( @@ -22,17 +27,39 @@ class FiseScreenController @Inject constructor( private const val ACTION_SCREEN_ON = "com.fise.turn_screen_on" /** FISE ROM 熄屏广播 */ private const val ACTION_SCREEN_OFF = "com.fise.turn_screen_off" + /** 唤醒 WakeLock 持有时间(毫秒),持有后自动释放 */ + private const val WAKE_LOCK_TIMEOUT_MS = 3000L + /** WakeLock tag */ + private const val WAKE_LOCK_TAG = "xqwatch:screen_wake" } + private val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager + /** 获取屏幕是否亮着(通过 PowerManager 标准 API) */ override fun isScreenOn(): Boolean { - val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager - return pm.isScreenOn + return powerManager.isScreenOn } - /** 亮屏:发送 FISE ROM 自定义广播 */ + /** + * 亮屏:WakeLock 唤醒硬件 + FISE 广播同步 ROM 状态 + * ACQUIRE_CAUSES_WAKEUP: 即使屏幕休眠也强制点亮 + * ON_AFTER_RELEASE: 释放后按系统超时计时(不立即灭) + */ + @Suppress("DEPRECATION") // FULL_WAKE_LOCK 在 API 27 上仍有效 override fun turnOn() { Timber.d("屏幕控制: 亮屏") + // 屏幕休眠时需要 WakeLock 强制唤醒硬件 + if (!powerManager.isScreenOn) { + val wakeLock = powerManager.newWakeLock( + PowerManager.FULL_WAKE_LOCK + or PowerManager.ACQUIRE_CAUSES_WAKEUP + or PowerManager.ON_AFTER_RELEASE, + WAKE_LOCK_TAG + ) + wakeLock.acquire(WAKE_LOCK_TIMEOUT_MS) + Timber.d("屏幕控制: WakeLock 唤醒(${WAKE_LOCK_TIMEOUT_MS}ms后自动释放)") + } + // FISE 广播确保 ROM 层面同步 context.sendBroadcast(Intent(ACTION_SCREEN_ON)) }