将数据从通知发送到活动类而不重新启动意图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将数据从通知发送到活动类而不重新启动意图相关的知识,希望对你有一定的参考价值。

我正在使用FCM从我的服务器向我的设备发送通知数据有效负载。当应用程序关闭或在后台时,我强制他们重新启动登录过程,这是我的Initialize.class文件。

Here is the onMessageReceived handler I am currently using.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    Log.e(TAG, "A notification packet was received from Firebase.");
    if (remoteMessage.getData() != null) {
        Log.e(TAG, "Notification Type: DATA");
        String title = remoteMessage.getData().get("title");
        String body = remoteMessage.getData().get("body");
        String image = remoteMessage.getData().get("image");
        MyNotificationManager.getInstance(getApplicationContext()).displayNotification(title, body, image);
    } else if (remoteMessage.getNotification() != null) {
        Log.e(TAG, "Notification Type: NOTIFICATION");
        String title = remoteMessage.getNotification().getTitle();
        String body = remoteMessage.getNotification().getBody();
        MyNotificationManager.getInstance(getApplicationContext()).displayNotification(title, body, "logo");
    }
}

当应用程序在前台时,我将重新发送Browser.class作为意图。问题是当您第一次运行Initialize时,它正在创建一个oneTimeSignOn令牌并记录您/创建一个新会话。由于您在浏览应用程序时已经登录,这对我来说并不重要,我只需要向他们发送浏览器类应该导航到的新页面,而无需重新启动该类。

void displayNotification(String title, String body, String image) {
 .....
    Class launchIntent = Browser.class;
    if (isAppIsInBackground(context)) {
        launchIntent = Initialize.class;
    }
    Intent intent = new Intent(context, launchIntent);
    intent.putExtra("NOTIFICATION_PACKET", "CONTENT");
    PendingIntent pendingIntent = PendingIntent.getActivity(mCtx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    mBuilder.setContentIntent(pendingIntent);
}

有没有办法将有效负载信息发送到我的Browser.class上的onResume运算符而不是传递intent.putExtra,所以我不需要重新加载整个活动?这导致的一个大问题是它将多个浏览器活动堆叠到第一个上。

有没有更好的方法来检查活动是离线还是仅在后台?这是我目前的检查方式

private static boolean isAppIsInBackground(Context context) {
    boolean isInBackground = true;
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
    for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
        if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            for (String activeProcess : processInfo.pkgList) {
                if (activeProcess.equals(context.getPackageName())) {
                    isInBackground = false;
                }
            }
        }
    }
    return isInBackground;
}
答案

所以我找到了一种让它发挥作用的方法。不确定这是否是hacky,但它的确有效!

首先将.BrowserandroidManifest设置为以下内容:

android:launchMode="singleTask"

然后在Browser.class中我们添加以下方法

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}

最后,在onResume函数中,我们覆盖并添加以下的tidbit

@Override
protected void onResume() {
    super.onResume();
    Intent intent = getIntent();
    if (intent.hasExtra("NOTIFICATION_PACKET")) {
        Log.e(TAG, "The following data was received from the notification packet: " + getIntent().getStringExtra("NOTIFICATION_PACKET"));
        getIntent().removeExtra("NOTIFICATION_PACKET");
    }
}

现在我们可以使用数据包信息并立即将其销毁,以便在重新启动应用程序时不会再次调用它。这使应用程序位于堆栈顶部,并且在应用程序位于前台时不会重新启动它。 :)

以上是关于将数据从通知发送到活动类而不重新启动意图的主要内容,如果未能解决你的问题,请参考以下文章

从通知意图启动活动时重新创建 Android ViewModel

在Android中将数据从活动发送到片段

将数据从活动发送到另一个而不启动它

如何将活动中的意图传递给已打开的片段

从 android 推送通知单击启动时,意图数据未在活动中更新

将微调器值从片段传递到活动