From 1cb795964819cfdd26cbd53c1842e54851d51bb9 Mon Sep 17 00:00:00 2001 From: Irena Szukala Date: Mon, 16 Feb 2026 14:03:47 +0100 Subject: [PATCH 1/2] Fix Android deep link push notifications causing app restart in foreground When the app is in the foreground and receives an Intercom push notification with a deep link, the app was unexpectedly restarting (showing splash screen) before navigating to the deep link destination. Root cause: - handleRemotePushMessage() always added the launch intent to TaskStackBuilder - getLaunchIntentForPackage() returns an intent with FLAG_ACTIVITY_NEW_TASK - This caused the app to restart even when already in foreground Solution: - Added isAppInForeground() helper method to detect app state - Only add launch intent to TaskStackBuilder when app is in background/killed - When app is in foreground, use empty TaskStackBuilder for direct navigation Changes: - Modified android/src/newarch/IntercomModule.java - Modified android/src/oldarch/IntercomModule.java - Added ActivityManager and Context imports - Added isAppInForeground() private static method - Updated handleRemotePushMessage() to check app state Benefits: - Foreground: Deep links navigate directly without app restart - Background/Killed: Behavior unchanged, app launches then navigates - No breaking changes, maintains backward compatibility --- android/src/newarch/IntercomModule.java | 47 +++++++++++++++++++++++-- android/src/oldarch/IntercomModule.java | 47 +++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/android/src/newarch/IntercomModule.java b/android/src/newarch/IntercomModule.java index c892bd10..061159e2 100644 --- a/android/src/newarch/IntercomModule.java +++ b/android/src/newarch/IntercomModule.java @@ -1,7 +1,9 @@ package com.intercom.reactnative; import android.app.Activity; +import android.app.ActivityManager; import android.app.Application; +import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast; @@ -90,10 +92,16 @@ public static void handleRemotePushWithCustomStack(@NonNull Application applicat public static void handleRemotePushMessage(@NonNull Application application, RemoteMessage remoteMessage) { try { TaskStackBuilder customStack = TaskStackBuilder.create(application); - Intent launchIntent = application.getPackageManager().getLaunchIntentForPackage(application.getPackageName()); - if (launchIntent != null) { - customStack.addNextIntent(launchIntent); + + // Only add launch intent if app is not in foreground + // This prevents the app from restarting when handling deep links while in foreground + if (!isAppInForeground(application)) { + Intent launchIntent = application.getPackageManager().getLaunchIntentForPackage(application.getPackageName()); + if (launchIntent != null) { + customStack.addNextIntent(launchIntent); + } } + handleRemotePushWithCustomStack(application, remoteMessage, customStack); } catch (Exception err) { Log.e(NAME, "handleRemotePushMessage error:"); @@ -101,6 +109,39 @@ public static void handleRemotePushMessage(@NonNull Application application, Rem } } + /** + * Checks if the application is currently in the foreground. + * + * @param application The application context + * @return true if the app is in the foreground, false otherwise + */ + private static boolean isAppInForeground(@NonNull Application application) { + try { + ActivityManager activityManager = (ActivityManager) application.getSystemService(Context.ACTIVITY_SERVICE); + if (activityManager == null) { + return false; + } + + List appProcesses = activityManager.getRunningAppProcesses(); + if (appProcesses == null) { + return false; + } + + final String packageName = application.getPackageName(); + for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { + if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND + && appProcess.processName.equals(packageName)) { + return true; + } + } + return false; + } catch (Exception err) { + Log.e(NAME, "isAppInForeground error:"); + Log.e(NAME, err.toString()); + return false; + } + } + public static void sendTokenToIntercom(Application application, @NonNull String token) { if (application == null || token == null || token.isEmpty()) { Log.w(NAME, "sendTokenToIntercom: application or token is null or empty"); diff --git a/android/src/oldarch/IntercomModule.java b/android/src/oldarch/IntercomModule.java index 32afd733..5b0d28f7 100644 --- a/android/src/oldarch/IntercomModule.java +++ b/android/src/oldarch/IntercomModule.java @@ -1,7 +1,9 @@ package com.intercom.reactnative; import android.app.Activity; +import android.app.ActivityManager; import android.app.Application; +import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast; @@ -82,10 +84,16 @@ public static void handleRemotePushWithCustomStack(@NonNull Application applicat public static void handleRemotePushMessage(@NonNull Application application, RemoteMessage remoteMessage) { try { TaskStackBuilder customStack = TaskStackBuilder.create(application); - Intent launchIntent = application.getPackageManager().getLaunchIntentForPackage(application.getPackageName()); - if (launchIntent != null) { - customStack.addNextIntent(launchIntent); + + // Only add launch intent if app is not in foreground + // This prevents the app from restarting when handling deep links while in foreground + if (!isAppInForeground(application)) { + Intent launchIntent = application.getPackageManager().getLaunchIntentForPackage(application.getPackageName()); + if (launchIntent != null) { + customStack.addNextIntent(launchIntent); + } } + handleRemotePushWithCustomStack(application, remoteMessage, customStack); } catch (Exception err) { Log.e(NAME, "handleRemotePushMessage error:"); @@ -93,6 +101,39 @@ public static void handleRemotePushMessage(@NonNull Application application, Rem } } + /** + * Checks if the application is currently in the foreground. + * + * @param application The application context + * @return true if the app is in the foreground, false otherwise + */ + private static boolean isAppInForeground(@NonNull Application application) { + try { + ActivityManager activityManager = (ActivityManager) application.getSystemService(Context.ACTIVITY_SERVICE); + if (activityManager == null) { + return false; + } + + List appProcesses = activityManager.getRunningAppProcesses(); + if (appProcesses == null) { + return false; + } + + final String packageName = application.getPackageName(); + for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { + if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND + && appProcess.processName.equals(packageName)) { + return true; + } + } + return false; + } catch (Exception err) { + Log.e(NAME, "isAppInForeground error:"); + Log.e(NAME, err.toString()); + return false; + } + } + public static void sendTokenToIntercom(Application application, @NonNull String token) { intercomPushClient.sendTokenToIntercom(application, token); Log.d(NAME, "sendTokenToIntercom"); From f4c44b04aa3e5e763100cc3868cbff933c6ac50c Mon Sep 17 00:00:00 2001 From: Irena Szukala Date: Mon, 16 Feb 2026 16:11:33 +0100 Subject: [PATCH 2/2] code cleanup --- android/src/newarch/IntercomModule.java | 8 -------- android/src/oldarch/IntercomModule.java | 8 -------- 2 files changed, 16 deletions(-) diff --git a/android/src/newarch/IntercomModule.java b/android/src/newarch/IntercomModule.java index 061159e2..9814029a 100644 --- a/android/src/newarch/IntercomModule.java +++ b/android/src/newarch/IntercomModule.java @@ -93,8 +93,6 @@ public static void handleRemotePushMessage(@NonNull Application application, Rem try { TaskStackBuilder customStack = TaskStackBuilder.create(application); - // Only add launch intent if app is not in foreground - // This prevents the app from restarting when handling deep links while in foreground if (!isAppInForeground(application)) { Intent launchIntent = application.getPackageManager().getLaunchIntentForPackage(application.getPackageName()); if (launchIntent != null) { @@ -109,12 +107,6 @@ public static void handleRemotePushMessage(@NonNull Application application, Rem } } - /** - * Checks if the application is currently in the foreground. - * - * @param application The application context - * @return true if the app is in the foreground, false otherwise - */ private static boolean isAppInForeground(@NonNull Application application) { try { ActivityManager activityManager = (ActivityManager) application.getSystemService(Context.ACTIVITY_SERVICE); diff --git a/android/src/oldarch/IntercomModule.java b/android/src/oldarch/IntercomModule.java index 5b0d28f7..6d46d17a 100644 --- a/android/src/oldarch/IntercomModule.java +++ b/android/src/oldarch/IntercomModule.java @@ -85,8 +85,6 @@ public static void handleRemotePushMessage(@NonNull Application application, Rem try { TaskStackBuilder customStack = TaskStackBuilder.create(application); - // Only add launch intent if app is not in foreground - // This prevents the app from restarting when handling deep links while in foreground if (!isAppInForeground(application)) { Intent launchIntent = application.getPackageManager().getLaunchIntentForPackage(application.getPackageName()); if (launchIntent != null) { @@ -101,12 +99,6 @@ public static void handleRemotePushMessage(@NonNull Application application, Rem } } - /** - * Checks if the application is currently in the foreground. - * - * @param application The application context - * @return true if the app is in the foreground, false otherwise - */ private static boolean isAppInForeground(@NonNull Application application) { try { ActivityManager activityManager = (ActivityManager) application.getSystemService(Context.ACTIVITY_SERVICE);