You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已弃用SCREEN_DIM_WAKE_LOCK的替代方案:通知唤醒屏幕问题

解决通知到达时唤醒屏幕的替代方案

首先明确:你没法直接修改系统通知悬浮窗的WindowManager参数,因为系统通知的Window由SystemUI负责管理,第三方应用没有权限操作它。官方推荐的WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON是用于控制自己应用内的窗口/Activity的屏幕常亮,不适用于系统通知场景。

下面提供两种可行的替代实现方式:


方案一:使用兼容的WakeLock类型(快速适配)

虽然SCREEN_DIM_WAKE_LOCK被弃用,但你可以使用其他未被弃用的WakeLock组合来实现相同效果,同时保证版本兼容性。需要先在AndroidManifest中声明WAKE_LOCK权限:

<uses-permission android:name="android.permission.WAKE_LOCK" />

修改后的代码示例:

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    val pm = getSystemService(POWER_SERVICE) as PowerManager
    val isScreenOn = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
        pm.isInteractive
    } else {
        @Suppress("DEPRECATION")
        pm.isScreenOn
    }

    if (!isScreenOn) {
        // 用SCREEN_BRIGHT_WAKE_LOCK替代弃用的SCREEN_DIM_WAKE_LOCK
        val wakeLock = pm.newWakeLock(
            PowerManager.SCREEN_BRIGHT_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.ON_AFTER_RELEASE,
            "irfAuroraAlert:newNotificationWakeLock"
        )
        wakeLock.acquire(3000) // 自动3秒后释放锁
    }

    // 原有通知发送逻辑保持不变
    remoteMessage.data.let {
        it["new_alert"]?.let { body -> sendNotification(body) }
    }
    remoteMessage.notification?.let {
        it.body?.let { body -> sendNotification(body) }
    }
}
  • SCREEN_BRIGHT_WAKE_LOCK:保持屏幕高亮唤醒(若需低亮度,SCREEN_DIM_WAKE_LOCK虽已弃用但仍能在旧版本正常工作,不过优先推荐未弃用的类型)
  • ACQUIRE_CAUSES_WAKEUP:强制唤醒休眠状态的设备
  • ON_AFTER_RELEASE:释放锁后保持屏幕亮一段时间,优化用户体验

方案二:使用Notification的FullScreenIntent(合规推荐)

对于Android 10及以上版本,后台唤醒限制更严格,推荐使用通知的setFullScreenIntent方法,通过启动透明Activity实现屏幕唤醒,这种方式更符合系统规范,无需依赖弃用的WakeLock API。

步骤1:创建透明唤醒Activity

在AndroidManifest中声明透明Activity并配置主题:

<activity
    android:name=".WakeScreenActivity"
    android:theme="@style/TransparentActivityTheme"
    android:excludeFromRecents="true"
    android:launchMode="singleInstance"
    android:taskAffinity="" />

对应的透明主题:

<style name="TransparentActivityTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item>
    <item name="android:windowDisablePreview">true</item>
</style>

Activity实现代码:

class WakeScreenActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 设置屏幕常亮和锁屏显示标志
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
        
        // 延迟1秒后自动关闭Activity,用户无感知
        Handler(Looper.getMainLooper()).postDelayed({
            finish()
        }, 1000)
    }
}

步骤2:修改通知发送逻辑

在sendNotification方法中为通知设置FullScreenIntent:

private fun sendNotification(body: String) {
    val wakeIntent = Intent(this, WakeScreenActivity::class.java)
    val pendingWakeIntent = PendingIntent.getActivity(
        this,
        0,
        wakeIntent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )

    val notificationBuilder = NotificationCompat.Builder(this, "your_channel_id")
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle("新通知")
        .setContentText(body)
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        // 设置FullScreenIntent,通知到达时触发唤醒
        .setFullScreenIntent(pendingWakeIntent, true)

    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.notify(System.currentTimeMillis().toInt(), notificationBuilder.build())
}
  • setFullScreenIntent第二个参数设为true,表示设备锁定时也会启动Activity
  • 透明Activity会快速启动并关闭,用户几乎无感知,但能有效触发屏幕唤醒
  • 该方式无需申请WAKE_LOCK权限,更符合Android后台权限规范

内容的提问来源于stack exchange,提问作者orbital_mechanic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 20:59:55