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

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)

问题根因

  1. 通知渠道ID不匹配:手动创建的渠道ID为UPDATE_ALERT_ID,实际发通知用的是CHANNEL_ID,后者是系统默认创建的高优先级渠道,你修改的渠道参数完全不生效。
  2. Android 8.0以上通知优先级完全由通知渠道控制,单独调用setPriority()仅对Android 7.0及以下版本生效,高版本系统下该设置无效。
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 23:54:33