应用在后台/已终止时通知点击检测及启动机制咨询
Hey there! Let's walk through how to handle your app launching from notifications when it's in the background or fully killed, plus how to detect those notification tap events.
First, let's clarify what happens under the hood: when your app is killed or running in the background, tapping a notification triggers the PendingIntent you've attached. The system will first spin up your app's process (if it was killed) and then launch the target Activity specified in your Intent.
Looking at your current code, you're on the right track, but there's a key flag you should add to ensure reliable behavior across all states:
Intent intent; if (moduleId == 1) { intent = new Intent(this, SchemesActivity.class); } else if (moduleId == 2) { intent = new Intent(this, ProcedureActivity.class); } else { intent = new Intent(this, NotificationsActivity.class); } // Add both flags to handle background/killed states properly intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); // For Android 12+, use FLAG_IMMUTABLE (required for most cases) PendingIntent pendingIntent = PendingIntent.getActivity( this, moduleId, // Use a unique request code per notification to avoid overwriting intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE );
FLAG_ACTIVITY_NEW_TASK: This is critical because when your app isn't in the foreground, launching an Activity requires creating a new task stack (if one doesn't exist already). Without this, your Activity might fail to launch on some Android versions.FLAG_IMMUTABLE: Mandatory for Android 12 and above unless you need to dynamically modify thePendingIntentlater. It's more secure and avoids system warnings.- Unique request code (
moduleIdhere): Using a different value for each notification type ensures that eachPendingIntentis unique and doesn't get overwritten by subsequent notifications.
To tell if your Activity was launched from a notification tap, the simplest way is to pass a flag in your Intent and check it in the target Activity. Here's how:
Step 1: Add a marker extra to your Intent
When building the Intent for the PendingIntent, add a boolean extra to mark it as a notification launch:
intent.putExtra("LAUNCHED_FROM_NOTIFICATION", true); // You can also pass the moduleId here if you need it later intent.putExtra("MODULE_ID", moduleId);
Step 2: Check the flag in your Activity
You need to handle two scenarios:
- App was killed: The Activity will be created from scratch, so check the flag in
onCreate. - App was in background: The Activity might already exist in the task stack, so check the flag in
onNewIntent(and update the Intent to the latest one).
Here's the code to implement this:
public class SchemesActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_schemes); handleNotificationLaunch(getIntent()); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); // Update the Intent to the latest one from the notification tap handleNotificationLaunch(intent); } private void handleNotificationLaunch(Intent intent) { if (intent != null && intent.getBooleanExtra("LAUNCHED_FROM_NOTIFICATION", false)) { // This is a notification tap! Run your custom logic here int moduleId = intent.getIntExtra("MODULE_ID", 0); Toast.makeText(this, "Launched from notification for module: " + moduleId, Toast.LENGTH_SHORT).show(); // Example: Handle specific module actions switch (moduleId) { case 1: // Do something for Schemes module break; case 2: // Do something for Procedure module break; default: // Handle default case break; } } } }
This approach works consistently across both background and killed states, and it's easy to extend with additional data from your notification.
内容的提问来源于stack exchange,提问作者Mahesh Babariya

