From 9de14d3ac8dd2fe875c7297f7e1958ac19e4e7f6 Mon Sep 17 00:00:00 2001 From: Rohit <40559587+Rohit3523@users.noreply.github.com> Date: Fri, 27 Feb 2026 00:00:30 +0530 Subject: [PATCH] track app state in android --- .../chat/rocket/reactnative/MainActivity.kt | 27 ++++++++++++----- .../notification/CustomPushNotification.java | 29 +++++++++++++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/android/app/src/main/java/chat/rocket/reactnative/MainActivity.kt b/android/app/src/main/java/chat/rocket/reactnative/MainActivity.kt index e4ab65ceba1..18949216dbf 100644 --- a/android/app/src/main/java/chat/rocket/reactnative/MainActivity.kt +++ b/android/app/src/main/java/chat/rocket/reactnative/MainActivity.kt @@ -1,5 +1,5 @@ package chat.rocket.reactnative - + import com.facebook.react.ReactActivity import com.facebook.react.ReactActivityDelegate import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled @@ -10,15 +10,16 @@ import com.zoontek.rnbootsplash.RNBootSplash import android.content.Intent import android.content.res.Configuration import chat.rocket.reactnative.notification.NotificationIntentHandler - +import chat.rocket.reactnative.notification.CustomPushNotification + class MainActivity : ReactActivity() { - + /** * Returns the name of the main component registered from JavaScript. This is used to schedule * rendering of the component. */ override fun getMainComponentName(): String = "RocketChatRN" - + /** * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] @@ -29,15 +30,27 @@ class MainActivity : ReactActivity() { override fun onCreate(savedInstanceState: Bundle?) { RNBootSplash.init(this, R.style.BootTheme) super.onCreate(null) - + // Handle notification intents intent?.let { NotificationIntentHandler.handleIntent(this, it) } } - + + override fun onResume() { + super.onResume() + // Notify that app is in foreground + CustomPushNotification.setAppInForeground(true) + } + + override fun onPause() { + super.onPause() + // Notify that app is in background + CustomPushNotification.setAppInForeground(false) + } + public override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) setIntent(intent) - + // Handle notification intents when activity is already running NotificationIntentHandler.handleIntent(this, intent) } diff --git a/android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java b/android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java index 22339abd691..5ae5640adbf 100644 --- a/android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java +++ b/android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java @@ -1,5 +1,7 @@ package chat.rocket.reactnative.notification; +import android.app.Activity; +import android.app.Application; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -44,6 +46,9 @@ public class CustomPushNotification { // Shared state private static final Gson gson = new Gson(); private static final Map> notificationMessages = new ConcurrentHashMap<>(); + + // Track app foreground state + private static boolean isAppInForeground = false; // Constants public static final String KEY_REPLY = "KEY_REPLY"; @@ -68,6 +73,23 @@ public CustomPushNotification(Context context, Bundle bundle) { public static void clearMessages(int notId) { notificationMessages.remove(Integer.toString(notId)); } + + /** + * Sets the app foreground state. Should be called from MainActivity's lifecycle callbacks. + */ + public static void setAppInForeground(boolean inForeground) { + isAppInForeground = inForeground; + if (ENABLE_VERBOSE_LOGS) { + Log.d(TAG, "App foreground state changed to: " + (inForeground ? "FOREGROUND" : "BACKGROUND")); + } + } + + /** + * Checks if the app is currently in the foreground. + */ + public static boolean isAppInForeground() { + return isAppInForeground; + } public void onReceived() { String notId = mBundle.getString("notId"); @@ -267,6 +289,13 @@ private void handleVideoConfNotification(Bundle bundle, Ejson ejson) { } private void postNotification(int notificationId) { + // Don't show notification if app is in foreground + // In-app notifications are handled by the JavaScript layer + if (isAppInForeground()) { + Log.d(TAG, "App is in foreground, skipping native notification display"); + return; + } + Notification.Builder notification = buildNotification(notificationId); if (notification != null && notificationManager != null) { notificationManager.notify(notificationId, notification.build());