如何从onMessageReceived(FirebaseMessagingService)中找出当前(顶部)活动?

时间:2017-05-14 14:52:59

标签: android firebase push-notification firebase-cloud-messaging android-push-notification

我一直在各处搜索,但我们无法确定如何获取正在运行的Android应用程序的当前(顶级)活动

好的,我的方案是,当应用程序位于前台时,我收到了Firebase云消息传递数据负载,并且调用了 onMessageReceived (FirebaseMessagingService的子类) 。我需要找出用户正在查看的屏幕,然后决定解除它(finish())或发送一些数据(通过Extras / Bundle)并刷新视图。

那么,我如何找出当前的视图/活动是什么,并讨论或发送一些数据并导致视图刷新?

谢谢!

3 个答案:

答案 0 :(得分:2)

作为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);
    }

}

此代码以这样的方式注册和取消注册currentActivityReceiver,以确保广播接收器仅处于活动状态when the Activity is active.

如果您的应用中有大量活动,您可能希望创建一个抽象基类Activity类,并将onResume和onPause代码放入其中,并让您的其他活动继承该类。

您还可以将数据添加到onMessageReceived中名为“localMessage”的Intent中(例如使用localMessage.putExtra()),然后在接收器中检索该数据。

Kevin的答案的一个优点是他的方法不需要任何额外的权限(如GET_TASKS)。

另外,正如Kevin指出的那样,除了BroadcastReceiver之外,还有其他更便捷的方式在你的应用中传递消息(例如EventBusOtto)。恕我直言,这些都很棒,但它们需要一个额外的库,它会增加一些方法计数开销。而且,如果您的应用已经在很多其他地方使用了BroadcastReceivers,那么出于美观和维护的原因,您可能会觉得您不希望两种方式在应用中传递消息。 (也就是说,Eve​​ntBus非常酷,我觉得它比BroadcastReceivers简单。)

答案 1 :(得分:1)

我们得到当前前台运行的活动

    ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;

需要许可

<uses-permission android:name="android.permission.GET_TASKS"/>

答案 2 :(得分:1)

其他人发布了正确的答案然后将其删除了,所以我会再次发布:

您不需要确定最高活动。您的每项活动都应该听取FirebaseMessagingService的一些信号,并采取相应的措施。信号可以是Intent上的LocalBroadcastManager广播,也可以使用某种事件总线。