androidandroid-intentandroid-notificationsintentfilter

When I click on a notification, it creates 2 activities except launcher activity


I have 2 activities in my application: SplashActivity and MainActivity. SplashActivity is the launcher activity. After SplashActivity, I navigate to MainActivity using the startActivity(Intent(context,MainActivity::class.java)) function. I create local notifications in these activities and I want the respective activities to open when I click on these notifications. The problem starts here: When I click on a notification that opens SplashActivity on SplashActivity, everything works fine. However, when I click on a notification that opens MainActivity, instead of bringing the existing instance of MainActivity from the background to the foreground, it creates another instance of MainActivity. As a result, it appears as if there are 2 instances of the application running. What could be the reason for this? Could it be related to the intent filter in the manifest file? (targetSdk 33)

MainActivity looks like this (2 app instances):

Main Activity looks like this

Class that creates notifications:

class NotificationService(
    private val context: Context
) {
    private val notificationManager =
        context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

    fun showNotification(title: String, content: String) {
        val activityIntent = Intent(
            context,
            MainActivity::class.java
        )
        val activityPendingIntent = PendingIntent.getActivity(
            context,
            1,
            activityIntent,
            PendingIntent.FLAG_IMMUTABLE
        )

        val notification = NotificationCompat.Builder(
            context,
            NOTIFICATION_CHANNEL_ID
        )
            .setSmallIcon(R.drawable.logo_small)
            .setContentTitle(title)
            .setContentText(content)
            .setSound(null)
            .setContentIntent(activityPendingIntent)
            .build()

        notificationManager.notify(
            NOTIFICATION_ID,
            notification
        )
    }

}

I change MainActivity::class.java to SplashActivity::class.java depending on situation

Solutions i tried:

1. I added android:launchMode="singleTop" to MainActivity on Manifest file.

2. I changed intents on NotificationService like this:

val activityIntent = Intent(
            context,
            MainActivity::class.java
        ).apply {
            action = Intent.ACTION_MAIN
            addCategory(Intent.CATEGORY_LAUNCHER)
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
        }
        val activityPendingIntent = PendingIntent.getActivity(
            context,
            1,
            activityIntent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

I tried many flags like this. None of them worked.


Solution

  • In my case I changed activity Intent like this:

    val activityIntent = Intent(
                context,
                MainActivity::class.java
            ).apply {
                action = Intent.ACTION_MAIN
                addCategory(Intent.CATEGORY_HOME)
                flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
            }
            val activityPendingIntent = PendingIntent.getActivity(
                context,
                1,
                activityIntent,
                PendingIntent.FLAG_IMMUTABLE
            )
    

    and activity declaration on Manifest file like this:

    <activity
    android:name=".ui.main.MainActivity"
    android:exported="true"
    android:launchMode="singleTop"
    android:screenOrientation="portrait" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.HOME"/>
    </intent-filter>
    </activity>
    

    If there is any better solution to this problem please post an answer for fellow developers.