如何从 onMessageReceived (of FirebaseMessagingService) 中找出当前 (top) Activity?
Posted
技术标签:
【中文标题】如何从 onMessageReceived (of FirebaseMessagingService) 中找出当前 (top) Activity?【英文标题】:How to find out the current (top) Activity from onMessageReceived (of FirebaseMessagingService)? 【发布时间】:2017-05-14 14:52:59 【问题描述】:我一直在到处搜索,但不知道如何获取正在运行的 Android 应用程序的当前(***)活动。
好的,我的场景是我收到了一个 Firebase 云消息传递数据负载,而应用程序在前台并且调用了 onMessageReceived(FirebaseMessagingService 的子类) .我需要找出用户正在查看的屏幕,然后决定关闭(finish())它或发送一些数据(通过 Extras / Bundle)并刷新视图。
那么,我如何找出当前的 View / Activity 是什么并讨论或发送一些数据并导致视图刷新?
谢谢!
【问题讨论】:
【参考方案1】:作为对 Kevin Krumwiede 已经接受的答案的跟进,这里有一些实现细节,用于遵循他的方法的一种可能方式(任何错误都是我的):
创建一个可重用的广播接收器
public class CurrentActivityReceiver extends BroadcastReceiver
private static final String TAG = CurrentActivityReceiver.class.getSimpleName();
public static final String CURRENT_ACTIVITY_ACTION = "current.activity.action";
public static final IntentFilter CURRENT_ACTIVITY_RECEIVER_FILTER = new IntentFilter(CURRENT_ACTIVITY_ACTION);
private Activity receivingActivity;
public CurrentActivityReceiver(Activity activity)
this.receivingActivity = activity;
@Override
public void onReceive(Context sender, Intent intent)
Log.v(TAG, "onReceive: finishing:" + receivingActivity.getClass().getSimpleName());
if (<your custom logic goes here>)
receivingActivity.finish();
在您的每个活动中实例化并使用该广播接收器
public class MainActivity extends AppCompatActivity
private BroadcastReceiver currentActivityReceiver;
@Override
protected void onResume()
super.onResume();
currentActivityReceiver = new CurrentActivityReceiver(this);
LocalBroadcastManager.getInstance(this).
registerReceiver(currentActivityReceiver, CurrentActivityReceiver.CURRENT_ACTIVITY_RECEIVER_FILTER);
@Override
protected void onPause()
LocalBroadcastManager.getInstance(this).
unregisterReceiver(currentActivityReceiver);
currentActivityReceiver = null;
super.onPause();
最后,从您的 FirebaseMessagingService 中发送适当的广播
public class MyFirebaseMessagingService extends FirebaseMessagingService
@Override
public void onMessageReceived(RemoteMessage remoteMessage)
Intent localMessage = new Intent(CurrentActivityReceiver.CURRENT_ACTIVITY_ACTION);
LocalBroadcastManager.getInstance(MyApplication.this).
sendBroadcast(localMessage);
此代码注册和注销 currentActivityReceiver 以确保广播接收器仅处于活动状态when the Activity is active.
如果您的应用中有大量活动,您可能希望创建一个抽象的基本活动类并将 onResume 和 onPause 代码放入其中,并让您的其他活动从该类继承。
您还可以在 onMessageReceived 中将数据添加到名为“localMessage”的 Intent(例如,使用 localMessage.putExtra())并稍后在接收器中检索该数据。
Kevin 的回答的一个优点是他的方法不需要任何额外的权限(如 GET_TASKS)。
此外,正如 Kevin 所指出的,除了 BroadcastReceiver(例如 EventBus 和 Otto),还有其他更方便的方法可以在您的应用中传递消息。恕我直言,这些很棒,但它们需要一个额外的库,这会增加一些方法计数开销。而且,如果您的应用程序已经在许多其他地方使用了 BroadcastReceivers,那么出于美观和维护的原因,您可能会觉得您不希望在应用程序中使用 两种 方式来传递消息。 (也就是说,EventBus 很酷,我觉得它没有 BroadcastReceivers 那么麻烦。)
【讨论】:
很好的答案!我认为这应该被接受的答案【参考方案2】:我们得到当前前台运行的Activity
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
需要许可
<uses-permission android:name="android.permission.GET_TASKS"/>
【讨论】:
谢谢!我试过代码。两个问题: (1) getRunningTasks 已被弃用。以及(2)如何让 Activity 完成()呢? 是您的应用程序的活动还是可能是任何应用程序? 我得到的活动名称(即 ComponentName)正是我想要/预期的。现在我需要完成()它。我该怎么做? 另外,我没有设置 GET_TASKS 权限并且它有效(在我的模拟器中)。那我绝对需要那个吗? 请回答我的评论,以便我为您提供【参考方案3】:别人发了正确答案然后又删了,所以我再发一次:
您无需确定排名靠前的活动。您的每项活动都应该听取来自FirebaseMessagingService
的一些信号并采取适当的措施。信号可以是LocalBroadcastManager
上的Intent
广播,或者您可以使用某种事件总线。
【讨论】:
以上是关于如何从 onMessageReceived (of FirebaseMessagingService) 中找出当前 (top) Activity?的主要内容,如果未能解决你的问题,请参考以下文章
解析从 android onMessageReceived 上的 fcm 响应获得的 json
无法从 Android 中 FirebaseMessagingService 的 onMessageReceived 生成通知
如何禁用或启用onMessageReceived的firebase推送通知?
提交 onMessageReceived/onSlashCommand 事件时如何在 JDA 中获取公会 ID