检查应用程序是从通知还是图标启动的?

3

我正在实现FCM通知功能,我从后端收到了一条通知,但是它没有包含任何数据,只有一个标题。这意味着,如果当此通知到达时我的应用程序没有运行,并且用户打开此通知,则我的应用程序将被启动,并且在其意图中附加的“extras”和“data”为空。

是否有一种方法可以区分这个“空通知”启动和正常的“用户点击应用程序图标”启动应用程序的方式,以便在需要时将用户带到应用程序的“通知”部分?

这两种情况下,它们的意图中都没有数据和额外信息。


展示你的通知服务代码。在打开活动时,你可以添加一个布尔标志来区分它与正常的应用程序启动。 - undefined
当应用程序未运行时,服务不会在通知到达时运行。通知数据由Android操作系统传递给意图,而不是我的自定义FirebaseMessagingService。 - undefined
3个回答

0

在创建启动应用程序的Intent时,您需要使用putExtra(ID_KEY, id)方法,并且在您的onCreate()方法中,您可以使用getIntent().getExtras().getInt(ID_KEY)来检索传递的id。


谢谢你的回答。这里的问题不是由我的FirebaseMessagingService处理的通知。而是当我的应用程序和服务未运行时,接收到的通知通过意图传递给应用程序,当用户点击通知时。这就是我试图区分的情况。 - undefined

0
原来Android将整个通知包传递给应用程序的启动Intent的extras。我们的应用程序有一些代码,用于检查这些额外信息中是否存在特定的键,否则就会丢弃它们。通过这种方式,我们可以检查/添加一个操作到意图或者一个键/值对到额外信息中,以区分通知启动和应用程序图标启动,使用类似Priyaank和Rey建议的方法。
关于这个主题有一个常见的误解。您需要记住,如果应用程序在后台运行或被杀死,FirebaseMessagingService的onMessageReceived方法将不会被调用。一旦用户点击通知,Android将把通知传递给启动Intent(extras)。

0

是的,你可以。你可以为每个Intent指定它的action。就像这样:

private fun sendNotification(title: String, message: String) {
        // Firstly, you create an intent that will open an activity when user taps on your notification.
        val intent = Intent(this, ProfileScreenActivity::class.java)
            .putExtra(INTENT_EXTRA_FIREBASE_MESSAGE_TITLE, title) // Add Title
            .putExtra(INTENT_EXTRA_FIREBASE_MESSAGE_BODY, message) // Add Message
        
        // Optional, but it basically clears backstack and all hierarchy of open Fragments/Activities
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

        // Here is where we specify that this Intent comes from Firebase Service
        intent.action = INTENT_ACTION_FIREBASE_MESSAGE_DIALOG

        // Wrap all of this
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        // Standard code for creating and sending Notifications.
        val channelId = getString(R.string.firebase_default_notification_channel_id)
        val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val notificationBuilder = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_notification_icon)
            .setContentTitle(title)
            .setContentText(message)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .setPriority(NotificationCompat.PRIORITY_MAX)

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(channelId, DEFAULT_NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH)
            notificationManager.createNotificationChannel(channel)
        }

        notificationManager.notify(Random.nextInt(0, 100), notificationBuilder.build())
    }

然后,在用户点击通知时打开的Activity中,您需要执行以下操作:

// Check if any actions were passed to this Activity when it's started.
// If any actions were passed, we check what action was passed and proceed from there.
    intent.action?.let { action ->
                if (action == INTENT_ACTION_FIREBASE_MESSAGE_DIALOG) {
                    intent.extras?.let { extras ->
                        alertDialog.warning(this, extras.getString(INTENT_EXTRA_FIREBASE_MESSAGE_BODY), extras.getString(INTENT_EXTRA_FIREBASE_MESSAGE_TITLE))
                    }
                }
    
                if (action == INTENT_ACTION_INTERNET_DAYS_LEFT_DIALOG) {
                    intent.extras?.let { extras ->
                        alertDialog.warning(this, extras.getString(INTENT_EXTRA_INTERNET_DAYS_LEFT))
                    }
                }
            }

非常感谢您详细的解释。这里的问题不是由我的FirebaseMessagingService处理的通知引起的,而是在我的应用程序和服务未运行时到达的通知,当用户点击通知时通过意图传递给应用程序。这就是我试图区分的情况。 - undefined
@LucasP. 你能给我展示一段发送通知的代码吗?这是你所谈论的通知吗? - undefined
它们来自一个后端服务器,我无法访问,这些不是本地通知。 - undefined
所有从Firebase接收到的手机通知都由FirebaseMessagingService处理,所以只需使用我提供的代码,您就能实现您所需的功能。 - undefined
在对此进行了深入研究和全面测试后,我认为你是错误的,正如文档中所述。如果应用程序在后台运行或未运行,服务将不会被调用。Android操作系统会自动缓存和处理通知。请记住,通知是空的,它不包含任何要传递给服务的数据。我只需要知道应用程序是否从通知中启动。https://firebase.google.com/docs/cloud-messaging/android/receive#backgrounded - undefined
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接