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

应用未启动时如何保留Intent中的Extras参数?

问题

我的应用通过MyFirebaseMessagingService接收通知,通知的Intent指向作为启动页的Login Activity,目的是让未登录用户先登录再查看通知内容。目前遇到的问题:

  • 应用运行时,Intent的Extras能正常携带并转发至目标Activity;
  • 应用未运行时,点击通知启动应用后,Intent的Extras丢失——Bundle对象存在但没有原参数。

以下是相关代码:

通知生成代码(MyFirebaseMessagingService)

public void sendCheckInNotification(Context context, String messageBody, String messageTypeIn, String messageIdIn) {
        generateRequestCode(messageIdIn);
        Log.i(TAG, "MyFirebaseMessagingService: " + messageTypeIn + " " + messageIdIn + " sendCheckInNotification: ");
        sendingActivity = "NewCheckInNotification";
        Log.i(TAG, "MyFirebaseMessagingService sendCheckInNotification: sendingActivity= " + sendingActivity);
        Intent intent = new Intent (context,  Login.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.putExtra("checkInTablePrimaryKey", assignedCheckInTablePrimaryKey);
        intent.putExtra("checkInTableFirebaseKey", checkInTableFirebaseKey);
        intent.putExtra("sendingActivity", sendingActivity);
        Log.i(TAG, "MyFirebaseMessagingService sendCheckInNotification: extras added=  " + sendingActivity);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            pendingIntent = PendingIntent.getActivity(context, requestCode, intent,
                    PendingIntent.FLAG_IMMUTABLE); }
        else {
            pendingIntent = PendingIntent.getActivity(context, requestCode, intent,
                    PendingIntent.FLAG_ONE_SHOT);
        }

        String channelId = context.getResources().getString(R.string.new_check_in_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(context, channelId)
                        .setSmallIcon(R.drawable.ic_launcher)
                        .setContentTitle(context.getResources().getString(R.string.check_in_notifications_header))
                        .setContentText(messageBody)
                        .setStyle(new NotificationCompat.InboxStyle())
                        .setAutoCancel(true)
                        .setContentIntent(pendingIntent)
                        .setGroup(NEW_CHECK_IN_NOTIFICATION_GROUP)
                        .setSound(defaultSoundUri);

        NotificationManager notificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "New CheckingIn Notification",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        notificationManager.notify(requestCode /* ID of notification */, notificationBuilder.build());
}

Login Activity接收代码

extras = getIntent().getExtras();
        Log.i(TAG, "Login onCreate: extras= " + extras);
        if (extras != null) {
            sendingActivity = extras.getString("sendingActivity");
            Log.i(TAG, "Login onCreate: sendingActivity = " + sendingActivity);
            if (user != null) {
                Log.i(TAG, "Login onCreate: user is not logged in for notification");
                if ((sendingActivity.equals("NewCheckInNotification")) ||
                   (sendingActivity.equals("PeepsWatcherUpdateNotification")) ||
                   (sendingActivity.equals("CheckInUpdateNotification")) ||
                   (sendingActivity.equals("CheckInLocationProvidedNotification")) ||
                   (sendingActivity.equals("NewCheckInLocationRequestNotification")) ||
                   (sendingActivity.equals("NewCheckInRequestNotification")) ||
                   (sendingActivity.equals("NewCheckInRequestUpdateNotification")) ||
                   (sendingActivity.equals("NewCheckInChatMessageNotification")) ||
                   (sendingActivity.equals("NewCheckInPicturesNotification"))) {
                    Log.i(TAG, "Login onCreate: extras exist ");
                    setIntentForNextActivity();
                }
                else {
                        Log.e(TAG, "Login onCreate: unknown sendingActivity for Intent " + sendingActivity);
                    }
            }
            else {
                Log.i(TAG, "Login: user not logged in"  );
                String message = "You will be directed to your notification after logging in";
                CustomToast newtoast = new CustomToast(context,message);
                newtoast.show();
            }
        }

Manifest中Login Activity配置

<activity
            android:name="Login"
            android:exported="true"
            android:label="Peeps">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity> 

解决方案

1. 修正PendingIntent的Flags配置

应用未启动时,系统可能复用旧的PendingIntent导致Extras丢失,需要调整Flags确保Extras被正确保留:

  • Android M及以上版本,在FLAG_IMMUTABLE基础上添加FLAG_UPDATE_CURRENT;
  • 低版本直接使用FLAG_UPDATE_CURRENT替换FLAG_ONE_SHOT。

修改后的PendingIntent创建代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    pendingIntent = PendingIntent.getActivity(context, requestCode, intent,
            PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); 
} else {
    pendingIntent = PendingIntent.getActivity(context, requestCode, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);
}

2. 调整Activity启动模式与Intent Flags

当前Login作为Launcher Activity,FLAG_ACTIVITY_SINGLE_TOP在应用未启动时作用有限,可调整Intent Flags或Manifest配置:

  • 替换原有Intent Flags为FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASK,确保启动时正确传递Intent;
  • 或在Manifest中给Login设置android:launchMode="singleTask",避免重复创建实例并保证Intent传递。

修改Intent Flags示例:

Intent intent = new Intent(context, Login.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

3. 正确获取启动Intent

应用未启动时,系统可能传递Launcher的默认Intent而非通知Intent,需做适配:

  • 若设置了singleTask启动模式,重写onNewIntent()方法更新Intent并处理Extras;
  • 将Extras处理逻辑抽成独立方法,方便onCreate()和onNewIntent()复用。

示例代码:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent); // 更新为最新的通知Intent
    handleExtras(getIntent().getExtras());
}

private void handleExtras(Bundle extras) {
    if (extras != null) {
        sendingActivity = extras.getString("sendingActivity");
        Log.i(TAG, "Login handleExtras: sendingActivity = " + sendingActivity);
        // 原有的判断与跳转逻辑
        if (user != null) {
            // ... 后续处理
        } else {
            // 未登录提示逻辑
        }
    }
}

4. 确保RequestCode唯一性

验证generateRequestCode(messageIdIn)生成的requestCode是唯一值,避免不同通知的PendingIntent被复用,导致Extras被覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:07:06