Android 12中ExoPlayer通知异常显示在通知栏顶部问题求助

问题描述
通知可正常加载,但异常固定显示在通知栏最顶部位置。
- 复现环境:搭载Android 12系统的诺基亚X10设备
- 已尝试操作:调整通知重要性参数、调用
setPriority(PRIORITY_LOW)设置低优先级,均未解决问题
原有问题代码
通知渠道创建代码:
private fun createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val serviceChannel = NotificationChannel( UPDATE_ALERT_ID, UPDATE_ALERT, NotificationManager.IMPORTANCE_NONE ) serviceChannel.lightColor = Color.BLUE serviceChannel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager service.createNotificationChannel(serviceChannel) } }
通知构建逻辑:
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager createChannel(notificationManager) playerNotificationBuild = PlayerNotificationManager.Builder(this, NOTIFICATION_ID, CHANNEL_ID, object : PlayerNotificationManager.MediaDescriptionAdapter { override fun getCurrentContentTitle(player: Player): CharSequence { return activeAudio?.song_name.toString() } override fun createCurrentContentIntent(player: Player): PendingIntent? { val intent = Intent(applicationContext, MainActivity::class.java); return PendingIntent.getActivity( applicationContext, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) } override fun getCurrentContentText(player: Player): CharSequence? { return activeAudio?.song_artist } override fun getCurrentLargeIcon( player: Player, callback: PlayerNotificationManager.BitmapCallback ): Bitmap? { return BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher_foreground) } }).setNotificationListener(object : PlayerNotificationManager.NotificationListener { override fun onNotificationCancelled(notificationId: Int, dismissedByUser: Boolean) { super.onNotificationCancelled(notificationId, dismissedByUser) removeNotification() stopSelf() stopForeground(true) } override fun onNotificationPosted(notificationId: Int, notification: Notification, ongoing: Boolean) { super.onNotificationPosted(notificationId, notification, ongoing) if (ongoing) startForeground(notificationId, notification) else stopForeground(false) } }) playerNotificationManager = playerNotificationBuild!!.build() playerNotificationManager!!.setMediaSessionToken(mediaSession!!.sessionToken) playerNotificationManager!!.setSmallIcon(R.mipmap.ic_launcher_foreground) // playerNotificationManager!!.setControlDispatcher(DefaultControlDispatcher(0, 0)) playerNotificationManager!!.setPriority(PRIORITY_LOW) playerNotificationManager!!.setPlayer(mSimpleExoPlayer)
问题根因
- 通知渠道ID不匹配:手动创建的渠道ID为
UPDATE_ALERT_ID,实际发通知用的是CHANNEL_ID,后者是系统默认创建的高优先级渠道,你修改的渠道参数完全不生效。 - Android 8.0以上通知优先级完全由通知渠道控制,单独调用
setPriority()仅对Android 7.0及以下版本生效,高版本系统下该设置无效。 - Android 12对持续运行的媒体前台服务通知有强制排序逻辑,播放状态下始终保持前台服务会被系统固定在通知栏顶部。
修复方案
1. 修正通知渠道创建逻辑
统一渠道ID,清除旧渠道缓存,配置正确的低优先级渠道参数:
private fun createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // 删除旧的错误渠道,清除历史配置缓存 notificationManager.deleteNotificationChannel(UPDATE_ALERT_ID) val serviceChannel = NotificationChannel( CHANNEL_ID, // 必须和PlayerNotificationManager传入的渠道ID完全一致 "媒体播放通知", NotificationManager.IMPORTANCE_LOW // 媒体通知不要用IMPORTANCE_NONE,会导致控制按钮失效 ).apply { lightColor = Color.BLUE lockscreenVisibility = Notification.VISIBILITY_PRIVATE setSound(null, null) // 关闭通知提示音 enableVibration(false) // 关闭震动 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { setAllowBubbles(false) // 关闭气泡权限,避免额外优先级提升 } } notificationManager.createNotificationChannel(serviceChannel) } }
2. 适配Android 12前台服务逻辑
根据播放器播放状态切换前台服务状态,避免暂停状态下仍被系统强制置顶:
override fun onNotificationPosted(notificationId: Int, notification: Notification, ongoing: Boolean) { super.onNotificationPosted(notificationId, notification, ongoing) if (ongoing && mSimpleExoPlayer.isPlaying) { startForeground(notificationId, notification) } else { // 暂停时 detach 前台状态,保留通知但不触发系统强制排序 stopForeground(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) STOP_FOREGROUND_DETACH else 0) } }
3. 补充通知配置
移除无效的优先级设置,关闭会提升通知优先级的计时显示:
playerNotificationManager = playerNotificationBuild!!.build() playerNotificationManager!!.setMediaSessionToken(mediaSession!!.sessionToken) playerNotificationManager!!.setSmallIcon(R.mipmap.ic_launcher_foreground) playerNotificationManager!!.setUseChronometer(false) // 关闭持续计时,避免系统判定为高优先级常驻通知 // Android 8.0以上无需调用setPriority,优先级由渠道统一控制 playerNotificationManager!!.setPlayer(mSimpleExoPlayer)
最后验证步骤
修改完成后先卸载一次App再重新安装,彻底清除系统中缓存的旧通知渠道配置,即可解决通知固定置顶的问题。
内容的提问来源于stack exchange,提问作者EmmanuelDav
相关产品推荐
相关产品推荐

