Search Issue Tracker

By Design

By Design in 6000.6.X

Votes

0

Found in

6000.0.52f1

6000.3.10f1

6000.4.0b10

6000.5.0a7

6000.6.0a1

Issue ID

UUM-136204

Regression

No

[Android] Foreground Service restarts and a notification reappears when the App is closed

Android

-

Steps to reproduce:
1. Open the attached “IN-136128” project [^AndroidForegroundServiceIssue.zip]
2. Build and Install the Android Player
3. Make sure to enable notifications for the app on the device in Settings > Notifications > App Notifications. (Click on the drop down at the top (Normally this dropdown defaults to displaying "Most recent") and select "All apps")
4. Run the Android Player
5. Press the button in the app to start the foreground process
6. Swipe down from the top of the screen and you should see a notification from the app saying "Service is running - Foreground task in progress"
7. Dismiss the notification by swiping it away
8. Close the Player
9. Observe the notifications view

Actual Result: When the app is closed or re-opened, the foreground notification shows up again automatically
Expected Result: If the user dismisses the foreground service notification, it should stay dismissed unless the app explicitly starts the service again

Reproducible with: 6000.3.10f1, 6000.4.0b11, 6000.5.0a7

Testing Environment: macOS 26.3 (M3 Max)

Reproducible with these devices:
VLNQA00372 - Galaxy S21 5G (SM-G991U), CPU: Snapdragon 888, GPU: Adreno 660, OS: 12
VLNQA00641 - Google Pixel 9 (Pixel 9), CPU: -, GPU: Mali-G715, OS: 15

  1. Resolution Note:

    **Root Cause:** Unity calls `Process.killProcess()` from `onDestroy()`, sending a SIGKILL before the Android Activity Manager Service (AMS) can clean up foreground service records. AMS then spawns a new process to honor those records, causing the foreground service notification to reappear.

    **Engine Fix:** Identified as an engine-level issue. No fix planned in the near term, changing the process cleanup lifecycle is high-risk. Ideally Unity would use `finish()`/`finishAffinity()` instead of `Process.killProcess()`.

    **Workarounds (neither fully replicates native Android behavior):**

    - **WA1 (Recommended):** Override `onUnityPlayerQuitted()` in a custom `UnityPlayerActivity` to send a `STOP_FOREGROUND_ONLY` intent to the service before SIGKILL fires. This clears AMS's foreground obligation so the notification doesn't reappear. Service still restarts in a new process/PID. [Sample project](https://drive.google.com/file/d/1GyATaAk-H9866GbE4so27pLFVmRryq77/).

    **CustomUnityPlayerActivity.java:**

    ```java
    @Override
    public void onUnityPlayerQuitted() {
    Intent intent = new Intent(this, com.tapp.MyForegroundService.class);
    intent.setAction("STOP_FOREGROUND_ONLY");
    startService(intent);
    super.onUnityPlayerQuitted();
    }
    ```

    **MyForegroundService.java - onStartCommand():**

    ```java
    String action = intent != null ? intent.getAction() : null;
    if ("STOP_FOREGROUND_ONLY".equals(action)) {
    stopForeground(STOP_FOREGROUND_REMOVE);
    return START_NOT_STICKY;
    }
    ```

    - **WA2:** Run the service in a separate Android process (`android:process=":foreground_service"`). Isolates it from Unity's SIGKILL but introduces significant architectural constraints (separate VM, no shared memory, IPC required, unreliable SharedPreferences across processes).

  2. Resolution Note (6000.6.X):

    **Root Cause:** Unity calls `Process.killProcess()` from `onDestroy()`, sending a SIGKILL before the Android Activity Manager Service (AMS) can clean up foreground service records. AMS then spawns a new process to honor those records, causing the foreground service notification to reappear.

    **Engine Fix:** Identified as an engine-level issue. No fix planned in the near term, changing the process cleanup lifecycle is high-risk. Ideally Unity would use `finish()`/`finishAffinity()` instead of `Process.killProcess()`.

    **Workarounds (neither fully replicates native Android behavior):**

    - **WA1 (Recommended):** Override `onUnityPlayerQuitted()` in a custom `UnityPlayerActivity` to send a `STOP_FOREGROUND_ONLY` intent to the service before SIGKILL fires. This clears AMS's foreground obligation so the notification doesn't reappear. Service still restarts in a new process/PID. [Sample project](https://drive.google.com/file/d/1GyATaAk-H9866GbE4so27pLFVmRryq77/).

    **CustomUnityPlayerActivity.java:**

    ```java
    @Override
    public void onUnityPlayerQuitted() {
    Intent intent = new Intent(this, com.tapp.MyForegroundService.class);
    intent.setAction("STOP_FOREGROUND_ONLY");
    startService(intent);
    super.onUnityPlayerQuitted();
    }
    ```

    **MyForegroundService.java - onStartCommand():**

    ```java
    String action = intent != null ? intent.getAction() : null;
    if ("STOP_FOREGROUND_ONLY".equals(action)) {
    stopForeground(STOP_FOREGROUND_REMOVE);
    return START_NOT_STICKY;
    }
    ```

    - **WA2:** Run the service in a separate Android process (`android:process=":foreground_service"`). Isolates it from Unity's SIGKILL but introduces significant architectural constraints (separate VM, no shared memory, IPC required, unreliable SharedPreferences across processes).

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.