Notification Trampoline Restrictions — Android S+

If you are developing apps for Android and specifically when targeting Android 31 then you might come across this new restriction by Android where your app is not opening notifications on Android S+ then this might help you!

What is Notification Trampoline Restriction?

I assume that many of you might have not heard about this yet but notification trampoline restriction is been there for some time now.

As per official docs:

When users interact with notifications, some apps respond to notification taps by launching an app component that eventually starts the activity that the user finally sees and interacts with. This app component is known as a notification trampoline.

Some apps respond to notification taps by launching a Service or BroadcastReciever that starts the activity for the users. This behavior is known as Notification Trampoline.

Like many of you, I was doing the same thing, passing a broadcast receiver to the pending intent and then setting that as content action for the notification but now this is not gonna work and with Android S onwards this will not open your activity if your app is in the background or not running.

When your app tries to start an activity from a service or broadcast receiver that acts as a notification trampoline, the system prevents the activity from starting, and the following message appears in Logcat:

Indirect notification activity start (trampoline) from PACKAGE_NAME, \
this should be avoided for performance reasons.

While the Android Dev team is claiming that it would improve the app performance and UX, which is actually true but this also means that now you have to work around this before you target Android S+ (31). And with the latest Google Play policies now you have to target API level 31 by August 2022 and the higher API levels by a couple of years after its release or else your app will not be available to download on that SDK level.

(Source: Android Developer Docs)

 

 

Yes, This is happening…

How to Resolve this?

If your app starts an activity from a service or broadcast receiver that acts as a notification trampoline, then you need to complete the following migration steps:

  1. Create a PendingIntent an object that is associated with the activity that you want to show your user after they tap on the notification.
  2. Use the PendingIntent an object that you created in the previous step to pass it in the setContentIntent of your notification.

Below is a code snippet to help you understand:

val notificationActivityIntent = Intent(context, MainActivity::class.java)
// Create the TaskStackBuilder
val pendingIntent: PendingIntent? = TaskStackBuilder.create(context).run {
// Add the intent, which inflates the back stack
addNextIntentWithParentStack(notificationTrampolineActivityIntent)
// Get the PendingIntent containing the entire back stack
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
// mutability flag required when targeting Android12 or higher
}
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Notification Trampoline")
.setContentText("Notification trampoline restrictions fix")
.setContentIntent(pendingIntent) // add your pending intent here...
.setAutoCancel(true)
.build()
notificationManager.notify(getUniqueId(), notification)

Here you go, a few changes and your app would be good to go and will again start responding to notifications.

If your app was triggering some kind of analytics function in response to that notification opening in that service or broadcast, that might not work now as with the above snippet you will be opening the activity directly.

In order to still call the tracking functions, you can do either of the 2 things that depend on your use case.

  1. Move all the analytics code in your activity that is to be opened by the notification and manage the state there.
  2. Create a transparent activity that can be opened by the notification, trigger the analytics function, and then based on the notification redirect to the desired activity.

The latter one might be useful in case your notifications are triggered by a separate module but for the rest if you can choose the first one that would save a lot of resources.

To learn more about different types of pending Intents that can help you support different notification opening behaviors, follow the official documentation:

https://developer.android.com/training/notify-user/navigation

Originally published on Medium: Link Here