如何通过前台服务/接收器唤醒屏幕?相关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
相关产品推荐
相关产品推荐

