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

如何通过前台服务/接收器唤醒屏幕?相关API已废弃且受Activity限制

解决方案:前台服务唤醒屏幕(无需启动可见Activity)

1. 使用WindowManager创建透明悬浮窗(API 23+)

这种方式无需启动可见Activity,通过创建全屏透明Window触发屏幕唤醒,核心是利用FLAG_TURN_SCREEN_ON和FLAG_KEEP_SCREEN_ON两个Window标志,替代废弃的WakeLock相关方法。

实现步骤:

  • 声明权限:在AndroidManifest.xml中添加悬浮窗权限(API 23+需动态申请):
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    
  • 前台服务中创建透明Window:
    private fun wakeUpScreen() {
        val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
        val params = WindowManager.LayoutParams().apply {
            width = WindowManager.LayoutParams.MATCH_PARENT
            height = WindowManager.LayoutParams.MATCH_PARENT
            format = PixelFormat.TRANSLUCENT
            type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            } else {
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
            }
            flags = WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
        }
        val view = View(this)
        windowManager.addView(view, params)
        // 屏幕唤醒后延迟移除Window,避免闪屏
        Handler(Looper.getMainLooper()).postDelayed({
            windowManager.removeView(view)
        }, 1000)
    }
    
  • 动态申请悬浮窗权限(API 23+):
    在首次触发唤醒前检查权限,引导用户开启:
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
        val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                            Uri.parse("package:$packageName"))
        startActivity(intent)
    }
    

2. 结合高优先级通知唤醒屏幕(API 26+)

若只需通过通知提醒用户并唤醒屏幕,可配置高优先级通知渠道,配合通知的唤醒标志实现,无需额外创建Window。

实现步骤:

  • 创建高优先级通知渠道:
    val channel = NotificationChannel(CHANNEL_ID, "数据库更新通知", NotificationManager.IMPORTANCE_HIGH).apply {
        lockscreenVisibility = Notification.VISIBILITY_PUBLIC
    }
    val notificationManager = getSystemService(NotificationManager::class.java)
    notificationManager.createNotificationChannel(channel)
    
  • 发送带唤醒标志的通知:
    val notification = NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("数据已更新")
        .setContentText("您的数据库内容有新变化")
        .setSmallIcon(R.drawable.ic_notify)
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setCategory(NotificationCompat.CATEGORY_ALARM)
        .setFullScreenIntent(null, true) // 触发屏幕唤醒
        .build()
    // 更新前台服务通知
    startForeground(NOTIFICATION_ID, notification)
    

注意事项

  • API 31+中,FLAG_KEEP_SCREEN_ON在后台服务可能受限,建议先通过PowerManager.isInteractive()判断屏幕状态,按需触发唤醒。
  • 悬浮窗方案需用户授权,需在应用UI中明确引导用户开启权限。
  • 避免频繁触发屏幕唤醒,减少不必要的电量消耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 09:23:27