Android Kotlin全屏通知异常:锁屏/关机时无法弹出全屏界面
问题排查与解决方案
你遇到的核心问题是全屏Intent传错了对象,再加上缺少锁屏显示的必要配置,导致无法像原生闹钟那样弹出全屏页面。下面是具体修正步骤:
1. 修正AlarmReceiver中的全屏Intent参数
你在NotificationCompat.Builder里调用setFullScreenIntent()时,错误传入了对应广播的pendingIntent,而非指向AlarmPage的fullScreenPendingIntent。修改后的代码:
class AlarmReceiver : BroadcastReceiver() { val notificationId = 2 val channelID = "androidAlarm4" override fun onReceive(context: Context?, intent: Intent?) { context ?: return // 正确创建指向全屏页面的PendingIntent val fullScreenIntent = Intent(context, AlarmPage::class.java) val fullScreenPendingIntent = PendingIntent.getActivity( context, 1001, // 用唯一requestCode避免冲突 fullScreenIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) val sound = Uri.parse("android.resource://${context.packageName}/${R.raw.siren}") val notification = NotificationCompat.Builder(context, channelID) .setSmallIcon(R.drawable.notification_bg) .setContentTitle("Reminder ALARM") .setContentText("Work has to be done now!!") .setPriority(NotificationCompat.PRIORITY_HIGH) .setSound( sound, AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM).build() ) .setAutoCancel(true) .setCategory(NotificationCompat.CATEGORY_ALARM) .setFullScreenIntent(fullScreenPendingIntent, true) // 这里传入正确的PendingIntent .build() val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.notify(notificationId, notification) } }
2. 配置AlarmPage的Manifest属性
要让页面在锁屏/黑屏状态下显示,必须在AndroidManifest.xml中给AlarmPage添加以下属性:
<activity android:name=".AlarmPage" android:showOnLockScreen="true" android:showWhenLocked="true" android:turnScreenOn="true" android:excludeFromRecents="true" android:launchMode="singleInstance" />
3. 完善AlarmPage的唤醒与解锁逻辑
在AlarmPage的onCreate方法中添加代码,确保屏幕被唤醒并能在锁屏状态下交互:
class AlarmPage : AppCompatActivity() { private lateinit var stopReminder : Button override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Android 7.1+ 强制显示在锁屏上并唤醒屏幕 setShowWhenLocked(true) setTurnScreenOn(true) // Android 10+ 请求解锁屏幕(可选) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager keyguardManager.requestDismissKeyguard(this, null) } setContentView(R.layout.activity_alarm_page) init() stopReminder.setOnClickListener { // 关闭通知并结束当前页面 val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.cancel(2) finish() } } private fun init(){ stopReminder = findViewById(R.id.stopReminder) } }
4. 补充必要权限
在AndroidManifest.xml中添加权限,确保闹钟不受电池优化影响且能发送通知:
<!-- Android 13+ 通知权限 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- 忽略电池优化,避免闹钟被系统杀死 --> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> <!-- 唤醒屏幕权限 --> <uses-permission android:name="android.permission.WAKE_LOCK" />
在设置闹钟前,请求忽略电池优化(AddActivity的setAlarm方法开头添加):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager if (!powerManager.isIgnoringBatteryOptimizations(packageName)) { val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) intent.data = Uri.parse("package:$packageName") startActivity(intent) } }
额外注意事项
- 测试时用真机:部分模拟器对全屏Intent的支持存在问题
- 确保
notification_bg是符合系统要求的纯色小图标,否则通知可能无法正常显示 - 闹钟的
PendingIntent随机requestCode可能导致重复覆盖,建议用每个闹钟的唯一ID作为requestCode
内容的提问来源于stack exchange,提问作者Haitham Shalabi
相关产品推荐
相关产品推荐

