如何从(FirebaseMessagingService 的)onMessageReceived 中找出当前(顶部)Activity?
How to find out the current (top) Activity from onMessageReceived (of FirebaseMessagingService)?
我一直在到处搜索,但就是想不通如何获取 运行 Android 应用程序的当前(顶部)activity.
好吧,我的场景是我在应用程序处于前台时收到 Firebase 云消息传递 数据有效负载 并且 onMessageReceived( FirebaseMessagingService 的子类)被调用。我需要找出用户正在查看的屏幕,然后决定关闭(finish())它或发送一些数据(通过 Extras / Bundle)并刷新视图。
那么,我如何找出当前视图/Activity并讨论或发送一些数据并导致视图刷新?
谢谢!
我们得到当前前景运行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"/>
其他人 post 编辑了正确的答案然后删除了它,所以我会 post 再说一遍:
您不需要确定顶部 activity。您的每个活动都应该监听来自 FirebaseMessagingService
的一些信号并采取适当的行动。信号可以是 LocalBroadcastManager
上的 Intent
广播,或者您可以使用某种事件总线。
作为对 Kevin Krumwiede 已经接受的答案的跟进,这里有一些实现细节,可以遵循他的方法(任何错误都是我的):
创建可重复使用的 BroadcastReceiver
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();
}
}
}
在您的每个活动中实例化并使用 BroadcastReceiver
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);
}
}
此代码以确保广播接收器仅处于活动状态的方式注册和注销当前Activity接收器when the Activity is active.
如果您的应用程序中有大量 Activity,您可能需要创建一个抽象基础 Activity class 并将 onResume 和 onPause 代码放入其中,并让您的其他 Activity继承自 class。
您还可以在 onMessageReceived 中向名为 "localMessage" 的 Intent 添加数据(例如使用 localMessage.putExtra()),稍后在接收器中检索该数据。
凯文回答的一个优点是他的方法不需要任何额外的权限(比如 GET_TASKS)。
此外,正如 Kevin 指出的那样,除了 BroadcastReceiver(例如 EventBus and Otto)之外,还有其他更方便的方法可以在您的应用程序中传递消息。恕我直言,这些都很棒,但它们需要一个额外的库,这会增加一些方法计数开销。而且,如果您的应用程序已经在很多其他地方使用了 BroadcastReceivers,您可能会觉得,出于美观和维护的原因,您不希望有 两种 方式来传递消息应用程序。 (也就是说,EventBus 很酷,我觉得它比 BroadcastReceivers 更简单。)
我一直在到处搜索,但就是想不通如何获取 运行 Android 应用程序的当前(顶部)activity.
好吧,我的场景是我在应用程序处于前台时收到 Firebase 云消息传递 数据有效负载 并且 onMessageReceived( FirebaseMessagingService 的子类)被调用。我需要找出用户正在查看的屏幕,然后决定关闭(finish())它或发送一些数据(通过 Extras / Bundle)并刷新视图。
那么,我如何找出当前视图/Activity并讨论或发送一些数据并导致视图刷新?
谢谢!
我们得到当前前景运行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"/>
其他人 post 编辑了正确的答案然后删除了它,所以我会 post 再说一遍:
您不需要确定顶部 activity。您的每个活动都应该监听来自 FirebaseMessagingService
的一些信号并采取适当的行动。信号可以是 LocalBroadcastManager
上的 Intent
广播,或者您可以使用某种事件总线。
作为对 Kevin Krumwiede 已经接受的答案的跟进,这里有一些实现细节,可以遵循他的方法(任何错误都是我的):
创建可重复使用的 BroadcastReceiver
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();
}
}
}
在您的每个活动中实例化并使用 BroadcastReceiver
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);
}
}
此代码以确保广播接收器仅处于活动状态的方式注册和注销当前Activity接收器when the Activity is active.
如果您的应用程序中有大量 Activity,您可能需要创建一个抽象基础 Activity class 并将 onResume 和 onPause 代码放入其中,并让您的其他 Activity继承自 class。
您还可以在 onMessageReceived 中向名为 "localMessage" 的 Intent 添加数据(例如使用 localMessage.putExtra()),稍后在接收器中检索该数据。
凯文回答的一个优点是他的方法不需要任何额外的权限(比如 GET_TASKS)。
此外,正如 Kevin 指出的那样,除了 BroadcastReceiver(例如 EventBus and Otto)之外,还有其他更方便的方法可以在您的应用程序中传递消息。恕我直言,这些都很棒,但它们需要一个额外的库,这会增加一些方法计数开销。而且,如果您的应用程序已经在很多其他地方使用了 BroadcastReceivers,您可能会觉得,出于美观和维护的原因,您不希望有 两种 方式来传递消息应用程序。 (也就是说,EventBus 很酷,我觉得它比 BroadcastReceivers 更简单。)