You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 12 Notification trampoline restrictions下SDK通知点击重复启动应用的问题咨询

Solutions for Android 12 Notification Trampoline & App State Issues

Hey there! I’ve wrestled with exactly these Android 12 notification restrictions before, so let’s walk through each of your questions with practical, actionable solutions:

1. How to check if the app is alive and in foreground/background?

The most reliable way is to use ActivityLifecycleCallbacks to track your app’s state. Here’s how to set it up:

  • Create a custom lifecycle handler class:

    class AppLifecycleHandler : Application.ActivityLifecycleCallbacks {
        private var foregroundActivities = 0
        private var isChangingConfiguration = false
    
        var isAppInForeground: Boolean = false
            private set
    
        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
        override fun onActivityStarted(activity: Activity) {
            foregroundActivities++
            if (foregroundActivities == 1 && !isChangingConfiguration) {
                isAppInForeground = true
            }
        }
        override fun onActivityResumed(activity: Activity) {}
        override fun onActivityPaused(activity: Activity) {}
        override fun onActivityStopped(activity: Activity) {
            foregroundActivities--
            isChangingConfiguration = activity.isChangingConfigurations
            if (foregroundActivities == 0 && !isChangingConfiguration) {
                isAppInForeground = false
            }
        }
        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle?) {}
        override fun onActivityDestroyed(activity: Activity) {}
    }
    
  • Register it in your Application class:

    class MyApp : Application() {
        val appLifecycleHandler = AppLifecycleHandler()
    
        override fun onCreate() {
            super.onCreate()
            registerActivityLifecycleCallbacks(appLifecycleHandler)
        }
    }
    

Then you can call (application as MyApp).appLifecycleHandler.isAppInForeground to check the state. For checking if the app is alive (even in background), this handler covers most use cases – if you need to verify the process is running, you can use ActivityManager.getRunningAppProcesses() as a fallback.

2. How to get the current top Activity in the stack?

Before Android 11, ActivityManager.getRunningTasks() worked, but it’s deprecated now. Instead, maintain your own activity stack using the same lifecycle handler:

  • Update the AppLifecycleHandler to track the top activity:
    private val activityStack = mutableListOf<Activity>()
    
    var topActivity: Activity? = null
        private set
    
    override fun onActivityStarted(activity: Activity) {
        // ... existing foreground tracking code
        activityStack.remove(activity)
        activityStack.add(activity)
        topActivity = activityStack.lastOrNull()
    }
    
    override fun onActivityStopped(activity: Activity) {
        // ... existing foreground tracking code
        if (!activity.isChangingConfigurations) {
            activityStack.remove(activity)
            topActivity = activityStack.lastOrNull()
        }
    }
    

Now appLifecycleHandler.topActivity gives you the current top activity. Just handle null cases (when the app is in background with no active activities).

3. Solutions for the "app restarts on every notification click" issue

This is a super common pain point with Android 12’s trampoline restrictions. Here’s the fix I’ve implemented successfully:

Step 1: Configure MainActivity’s launch mode

In your AndroidManifest.xml, set launchMode="singleTop" for MainActivity:

<activity
    android:name=".MainActivity"
    android:launchMode="singleTop">
    <!-- ... other attributes -->
</activity>

This ensures that if MainActivity is already at the stack top, it won’t restart – instead, onNewIntent() will be called.

Step 2: Build the PendingIntent conditionally

When creating the notification’s PendingIntent, check if the app is in foreground. If it is, directly launch your WebView activity (or pass data to the top activity). If not, launch MainActivity with the necessary data:

val pendingIntent = if (appLifecycleHandler.isAppInForeground) {
    // Launch WebView activity directly if app is foreground
    Intent(this, WebViewActivity::class.java).apply {
        putExtra("NOTIFICATION_URL", yourTargetUrl)
    }.let { intent ->
        PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
    }
} else {
    // Launch MainActivity with data to trigger WebView later
    Intent(this, MainActivity::class.java).apply {
        putExtra("LAUNCH_WEBVIEW", true)
        putExtra("NOTIFICATION_URL", yourTargetUrl)
        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
    }.let { intent ->
        PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
    }
}

Step 3: Handle the intent in MainActivity’s onNewIntent()

Add this to MainActivity to avoid restarting and process the notification data:

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    intent?.let {
        if (it.getBooleanExtra("LAUNCH_WEBVIEW", false)) {
            val targetUrl = it.getStringExtra("NOTIFICATION_URL")
            targetUrl?.let { url ->
                // Launch WebView activity or update UI directly
                startActivity(Intent(this, WebViewActivity::class.java).apply {
                    putExtra("NOTIFICATION_URL", url)
                })
            }
        }
    }
}

Key Notes:

  • Always use FLAG_IMMUTABLE for PendingIntents on Android 12+ – mutable ones can trigger trampoline restrictions.
  • If your WebView is part of MainActivity (not a separate activity), skip launching a new activity and just update the UI in onNewIntent().

I’ve seen dozens of devs hit this exact issue after Android 12 rolled out, and this approach works consistently across devices.

内容的提问来源于stack exchange,提问作者jerald jacob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:57:42