【问题标题】:resume current activity by notification通过通知恢复当前活动
【发布时间】:2017-12-13 11:22:57
【问题描述】:

我在我的应用中使用FCM (Firebase Cloud Messaging)。

我的应用中有 N 个活动

在应用程序的生命周期中,它可能有任何活动堆栈:

Activity1 ->Activity2 -> Activity3-> ... -> ActivityN

我要实现的行为:

  1. 转到ActivityN
  2. 将应用程序转为后台
  3. 点击通知
  4. 在 ActivityN 上将应用程序转至前台
  5. 在 ActivityN 上显示对话框

如何实现呢?

【问题讨论】:

  • 你解决了吗?

标签: android notifications activity-stack


【解决方案1】:

我有同样的问题,我希望应用程序在 Firebase 后台通知到达时恢复其当前状态。我的部分解决方案来自this 答案。

就我而言,堆栈中最多有四个活动:A->B->C->D。

  1. 在我的应用清单中,我将活动 D 设置为 singleTask 活动 (launchMode="singleTask") 并将意图过滤器放入该活动中。

    <activity android:name=".activityD"> <intent-filter> <action android:name=".activityD" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>

  2. 然后我将活动 D 作为“click_action”放入 Firebase 消息传递发送的通知中。

  3. 在我的例子中,我没有覆盖活动 D 中的 onNewIntent() 方法,因为 FirebaseMessageService 的 onMessageReceived 方法将在应用程序进入前台时被调用。
  4. 最重要的是:因为活动 D 是一个单任务活动,它仅在它尚未在堆栈中时才被创建。因此,在活动 D 的 onCreate() 方法中,我检查了 Intent extras 的内容。如果额外内容不是来自活动 C,我会立即弹出 D (finish();return;),因为我知道它是由 Firebase 通知创建的。这会在应用程序进入后台时恢复应用程序的活动(A、B 或 C)。如果应用程序进入后台时的 Activity 为 D,则将调用 onNewIntent() 方法而不是 onCreate() 在这种情况下,我不执行步骤 #3 中所述的任何操作。

再考虑之后,一个更通用的解决方案是使用意图过滤器创建一个“虚拟”singleTask 活动,然后始终在 onCreate() 方法中将其从堆栈中弹出以恢复当前活动放在后台。肯定有更好的方法……我就是找不到。

【讨论】:

  • 完美答案!我认为这是目前我能找到的最好的!谢谢!
【解决方案2】:

在FirebaseMessagingService 类中>> onMessageRecived

Intent intent = new Intent(this, ActivityN.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                FLAG_ONE_SHOT);


    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable._logo)
            .setContentText(notification)
            .setContentTitle(title)
            .setAutoCancel(true)
            .setSound(defaultSoundUri);
            .setContentIntent(pendingIntent);

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

    notificationManager.notify(0, notificationBuilder.build());

【讨论】:

  • 如何知道我应该放置什么活动而不是 ActivityN?在activity-stack的最后一个位置可以有应用程序的任何activity
  • 在 Gloabal Activity 中创建一个静态全局变量 Like AactivityName =this and wehenver 你去新的 Activity 改变它就像 activityName =this;并检查 Firebase 服务中的名称为 GloabalActivity.ActivityName;
【解决方案3】:

如果您不确定要在 Notification click 上打开哪个 Activity。然后你应该在 Notification click 上广播。 创建一个广播接收器。

   class NotificationClickReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        // here you will get Intent
        // Check which activity is currently open and pass the data to it
        // For passing data you can use a Another BroadcastReceiver or
    }
}

清单中的条目

<receiver
        android:name=".NotificationClickReceiver"
        />

然后在通知点击时使用 pendingIntent 获取广播

Intent intent = new Intent(this, NotificationClickReceiver.class);
    intent.putExtra("key","val");
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 3, intent,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable._logo)
            .setContentText(notification)
            .setContentTitle(title)
            .setAutoCancel(true)
            .setSound(defaultSoundUri);
        .setContentIntent(pendingIntent);

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

    notificationManager.notify(0, notificationBuilder.build());

现在您将在 NotificationClickReceiver 的 onReceive 中获得意图,然后您可以确定将其传递给哪个活动。

【讨论】:

  • 在您的回答中您声明了YourActivity,但是什么活动?当应用程序进入前台时,这可能是堆栈中的任何活动。此外,Intent.FLAG_ACTIVITY_CLEAR_TOP 将删除我堆栈中的所有其他活动。不应更改 Activity 堆栈,只能显示对话框。
  • 你想在点击通知时打开哪个活动。
  • 我想在应用程序转到后台时打开我的活动堆栈中的最后一个活动。可能是Activity1,Activity2,...ActivityN,不知道会是什么活动
  • 假设 Activity2 处于前台并且您向 Activity2 发出通知。现在用户单击返回并返回到 Activity1。现在用户单击通知,但它是针对 Activity2 的,因此它将打开 Activity2 。那样可以么 ?或者您想在这种情况下在 Activity1 中执行操作?
  • 查看我的更新答案,这是我可以建议的。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多