Как узнать текущую (верхнюю) активность из onMessageReceived (из FirebaseMessagingService)?
Я искал везде, но просто не могу понять, как получить текущую (верхнюю) активность запущенного приложения Android.
Хорошо, мой сценарий состоит в том, что я получил полезные данные Firebase Cloud Messaging Data, когда приложение находится на переднем плане, и вызывается onMessageReceived (из подкласса FirebaseMessagingService). Мне нужно выяснить, какой экран просматривает пользователь, а затем принять решение отклонить (завершить ()) его или отправить некоторые данные (с помощью Extras / Bundle) и обновить вид.
Итак, как мне узнать, что является текущим представлением / действием, обсудить или отправить некоторые данные и заставить представление обновиться?
Спасибо!
3 ответа
Кто-то опубликовал правильный ответ, а затем удалил его, поэтому я опубликую его снова:
Вам не нужно определять верхнюю активность. Каждое из ваших действий должно слушать некоторый сигнал от FirebaseMessagingService
и принять соответствующие меры. Сигнал может быть Intent
трансляция на LocalBroadcastManager
или вы могли бы использовать какую-то шину событий.
Так же, как продолжение уже принятого ответа Кевина Крумвиде, вот некоторые детали реализации одного возможного способа следовать его подходу (любые ошибки мои):
Создать многоразовый 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 таким образом, чтобы гарантировать, что широковещательный приемник активен, только когда активность активна.
Если в вашем приложении имеется большое количество Activity, вы можете захотеть создать абстрактный базовый класс Activity и поместить в него код onResume и onPause, а другие ваши Activity наследуют от этого класса.
Вы также можете добавить данные в Intent с именем "localMessage" в onMessageReceived (например, с помощью localMessage.putExtra()) и позднее получить эти данные в приемнике.
Одним из преимуществ ответа Кевина является то, что его подход не требует каких-либо дополнительных разрешений (например, GET_TASKS).
Кроме того, как указал Кевин, есть и другие, более удобные способы передачи сообщений вокруг вашего приложения, кроме BroadcastReceiver (например, EventBus и Otto). ИМХО, это здорово, но они требуют дополнительной библиотеки, которая добавит некоторые подсчеты методов. И, если ваше приложение уже использует BroadcastReceivers во многих других местах, вы можете почувствовать, что по эстетическим соображениям и из-за необходимости обслуживания вы не хотите иметь два способа передачи сообщений в приложении. (Тем не менее, EventBus довольно крутой, и я чувствую, что он менее громоздкий, чем BroadcastReceivers.)
Мы получаем текущий передний план
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
требуется разрешение
<uses-permission android:name="android.permission.GET_TASKS"/>