Lucas P.
Lucas P.

Reputation: 4532

Check if app was launched from a notification or icon?

I am implementing FCM notifications and I have a notification coming from my backend which does not contain any data, just a title. This means that if my app is not running while this notification arrives, and the user opens this notification, my app will be launched with null extras and data in its intent.

Is there a way to differentiate this "empty notification" launch from the normal "user tapped the the app icon" launch of the app so I can take the user to the "notifications" section of the app when needed?

Both cases have null data and extras in their intent.

Upvotes: 4

Views: 2389

Answers (4)

Quan Dang Anh
Quan Dang Anh

Reputation: 21

  1. When you open app from notification with null data, intent.extras has some keys in image below intent.extras key
  1. When you open app from notification with data, check your key in intent.extras
  2. When you open app from launcher, intent.extras has no key

Upvotes: 2

Lucas P.
Lucas P.

Reputation: 4532

Turns out Android delivers the whole notification bundle to the App's launch Intent extras. Our app had some code that was checking if a particular key existed in those extras, otherwise it was discarding them. This way we can check/add an action to the intent or a key/value pair to the extras to differentiate between a Notification Launch and an Icon Launch of the app, using something similar to what Priyaank and Rey suggested.

There is one common misconception about this topic. You need to keep in mind that the FirebaseMessagingService's onMessageReceived method will not get called if the app is in the background or killed. Android will deliver the notification to the launch Intent (extras), once the user clicks on the notification.

Upvotes: 0

vt-dev0
vt-dev0

Reputation: 773

Yes you can. What you can do is for each Intent specify its action. Like this:

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())
    }

Then inside your Activity that you're opening when user taps on your Notification, you do the following:

// 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))
                    }
                }
            }

Upvotes: 0

Priyaank
Priyaank

Reputation: 280

You need to use the putExtra(ID_KEY,id) when you create your Intent for starting your application, and in your onCreate() method you can use getIntent().getExtras().getInt(ID_KEY) to retrieve your passed id.

Upvotes: 0

Related Questions