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

Android集成Firebase Cloud Messaging后全屏意图通知无法触发的问题求助

Android集成Firebase Cloud Messaging后全屏意图通知无法触发的问题求助

看起来你已经在尝试实现类似来电的全屏意图通知,但遇到了无法触发全屏跳转的问题。我帮你分析下代码里可能存在的几个关键点,以及对应的修复方案:

一、权限缺失是高频问题

Android 12(API 31)及以上系统要求必须申请USE_FULL_SCREEN_INTENT权限才能使用全屏意图;Android 13(API 33)及以上还需要POST_NOTIFICATIONS权限发送通知。你需要先在AndroidManifest.xml中添加这些权限:

<!-- 全屏意图权限 -->
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<!-- Android 13+ 通知权限 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- 前台服务权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CALL" /> <!-- 通话类服务专用 -->

同时,在Android 13+设备上,需要在运行时动态申请POST_NOTIFICATIONS权限,用户授权后才能正常显示通知。

二、传递Notification对象的风险

你当前在navigate()方法中直接把Notification对象通过Intent传递给前台服务,这在跨进程场景下(Firebase服务到前台服务)很容易出现Parcelable序列化/反序列化失败的问题,导致前台服务拿到的notification为null,无法正确触发全屏意图。

修复方案:不要直接传递Notification,而是传递构建通知所需的参数(标题、内容等),在前台服务内部重新构建通知。

三、全屏Activity的配置优化

你的ReceiveMessage Activity需要配置为允许在锁屏状态下显示并唤醒屏幕,才能模拟来电的全屏效果:

1. AndroidManifest.xml中配置Activity属性

<activity
    android:name=".ReceiveMessage"
    android:showOnLockScreen="true"
    android:turnScreenOn="true"
    android:excludeFromRecents="true"
    android:launchMode="singleTask"
    android:screenOrientation="portrait" />

2. 在Activity内部添加Window Flags

在ReceiveMessage的onCreate()方法中添加以下代码,确保唤醒屏幕并全屏显示:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 设置Window Flags,确保锁屏时唤醒并全屏
    window.addFlags(
        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
        WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
        WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
        WindowManager.LayoutParams.FLAG_FULLSCREEN
    )
    setContentView(R.layout.activity_receive_message)
}

四、修改前台服务的实现

重构CallForegroundService,在服务内部重新构建通知和全屏PendingIntent:

class CallForegroundService : Service() {
    companion object {
        private const val TAG = "CallForegroundService"
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // 从Intent获取传递的通知参数
        val title = intent?.getStringExtra("title") ?: "Incoming Call"
        val content = intent?.getStringExtra("content") ?: "Someone is calling you..."
        val channelId = getString(R.string.CHANNEL_ID)

        // 重新构建全屏PendingIntent
        val activityIntent = Intent(this, ReceiveMessage::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
        }
        val fullScreenPendingIntent = PendingIntent.getActivity(
            this,
            0,
            activityIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
        )

        // 构建通知
        val notification = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle(title)
            .setContentText(content)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setCategory(NotificationCompat.CATEGORY_CALL)
            .setFullScreenIntent(fullScreenPendingIntent, true)
            .setAutoCancel(false)
            .setOngoing(true)
            // 可选:添加来电铃声和振动
            .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE))
            .setVibrate(longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400))
            .build()

        // 启动前台服务
        startForeground(1, notification)

        // 30秒后自动停止服务并移除通知
        Handler(Looper.getMainLooper()).postDelayed({
            stopForeground(STOP_FOREGROUND_REMOVE)
            stopSelf()
        }, 30000)

        return START_NOT_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? = null
}

五、修改FirebaseMessagingService的navigate方法

不再传递Notification对象,改为传递参数给前台服务:

private fun navigate() {
    val serviceIntent = Intent(this, CallForegroundService::class.java).apply {
        putExtra("title", "Incoming Call")
        putExtra("content", "Someone is calling you...")
    }
    ContextCompat.startForegroundService(this, serviceIntent)
}

六、优化通知渠道配置

在MyApplication中完善通知渠道的配置,添加铃声和振动增强提示:

class MyApplication: Application() {
    override fun onCreate() {
        super.onCreate()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = getString(R.string.channel_name)
            val descriptionText = getString(R.string.channel_description)
            val channelId = getString(R.string.CHANNEL_ID)
            val importance = NotificationManager.IMPORTANCE_HIGH
            val mChannel = NotificationChannel(channelId, name, importance).apply {
                description = descriptionText
                lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
                // 设置来电铃声和振动
                setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE), null)
                enableVibration(true)
                vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
            }
            val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(mChannel)
        }
    }
}

最后注意事项

测试时请在锁屏状态下验证,因为系统默认在设备解锁时只会弹出通知(避免打扰用户正常操作),只有锁屏时才会触发全屏意图。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 12:14:35