单击通知不会打开提及的活动

我正在尝试在单击通知时打开一个,下面是我的代码。Activity

Intent intent = new Intent(this.getApplicationContext(), NotificationActivity.class);
intent.putExtra("msgBody",messageBody);
intent.putExtra(Constants.NOTIF_INTENT_TYPE,Constants.NOTIF_INTENT_TYPE);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                |Intent.FLAG_ACTIVITY_SINGLE_TOP
                |Intent.FLAG_ACTIVITY_CLEAR_TOP); //Tried with many options here

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent,
                                         PendingIntent.FLAG_CANCEL_CURRENT);

Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.otp_icon)
                .setContentTitle("Push MSG")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

notificationManager.notify(0, notificationBuilder.build());

安卓清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.com.pushapp">

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="21" />

    <supports-screens
        android:anyDensity="true"
        android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="true" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:name=".AndroidPushApp"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher">
        <activity
            android:name=".PushSplashScreen"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainApplicationScreen"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
        </activity>
        <activity
            android:name=".StartActivity"
            android:launchMode="singleTask"
            android:screenOrientation="portrait"
            android:uiOptions="splitActionBarWhenNarrow"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
        </activity>

        <service android:name=".MyFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

        <service android:name=".MyFirebaseInstanceIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity
            android:name=".NotificationActivity"
            android:exported="true"
            android:label="@string/title_activity">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>

每当我收到来自FCM的通知时,我都会调用此通知。每当我单击通知时,通知活动都不会打开,而是应用程序正在打开(我通常的应用程序流)。每当我在应用程序已打开时收到通知时,就会打开,但当应用程序尚未打开时则不会打开。有人可以帮我解决这个问题吗?splash screen->starting activityNotificationActivity

注意:请我重申,当应用程序尚未打开状态时,单击通知时不会打开。NotificationActivity.class


答案 1

根据文档,用于接收和处理消息,FCM

如果要在应用处于前台时接收通知,则需要添加一些消息处理逻辑。

要接收消息,请使用扩展 FirebaseMessagingService 的服务。您的服务应重写 onMessageReceived 回调,该回调是针对大多数消息类型提供的,但以下情况除外:

1).当您的应用程序在后台时发送通知。在这种情况下,通知将传递到设备的系统托盘。默认情况下,用户点击通知会打开应用启动器。

同时具有通知和数据有效负载的消息,包括后台和前台。在这种情况下,通知将传递到设备的系统托盘,并且数据负载将以启动器活动意图的附加内容传递。

enter image description here

所以基本上,我们有两种类型的有效载荷

1). 通知负载

2). 数据有效负载

者(我们可以考虑的另一种类型)。

现在,让我们逐一讨论这些有效载荷。在此之前,你需要了解如何将这些有效负载发送到你的应用。您所要做的就是利用任何可以执行的工具。就我而言,我正在使用Postman工具,这是一个Google Chrome插件。HTTP POST Request

在做 for 之前,你必须考虑三件事:HTTP Post RequestFCM

HTTP发布请求网址:https://fcm.googleapis.com/fcm/send

2). 请求标头 :

i). 内容类型 : application/json

ii). 授权: 密钥 = YOUR_SERVER_KEY

下面是相同的屏幕截图,以显示它的外观。

enter image description here

3).身体:在这里我们将有和。JSONNotificationData Payloads

  • 因此,从通知有效负载开始,这是最简单的。在这种情况下,仅当应用位于 中时才调用,对于所有其他情况,它是一个 ,它在单击时打开 。当您不想自己控制并且没有太多数据要处理时,这很有用。您甚至可以控制声音,图标和click_action(仅当应用程序处于中时),而无需在.在下面的屏幕截图中附加了此类正文的一个示例。onMessageReceived()ForegroundSystem Tray NotificationLauncher ActivityNotificationsNotificationForegroundonMessageReceived()HTTP POST Request

enter image description here

要在发送click_action参数时打开所需的代码,您必须在 .ActivityonMessageReceived()

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    if (null != remoteMessage.getNotification().getClickAction()) {
            startActivity(remoteMessage.getNotification().getClickAction(), null, this);
    }
}

以下是您的方法:startActivity()

public void startActivity(String className, Bundle extras, Context context) {
    Class cls = null;
    try {
        cls = Class.forName(className);
    } catch (ClassNotFoundException e) {
        //means you made a wrong input in firebase console
    }
    Intent intent = new Intent(context, cls);
    if (null != extras) {
        intent.putExtras(extras);
    }
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
            | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    context.startActivity(intent);
}

注意:仅当应用程序处于前台时,此密钥才有效,对于应用程序处于“后台”并关闭的所有其他情况,它不起作用。如果指定了此参数,它甚至不会打开启动器活动(如果是“背景”和“已关闭”)。click_action

  • 现在是数据有效负载。这类似于 我们在 中遇到的那个。如果我们想自己处理所有事情,这一点非常重要,就像我们在.此类主体的示例如下所示。GCMNotificationGCMHTTP POST Request

enter image description here

因此,在这种情况下,每次都调用,这将以与 相同的方式工作,因此对我们所有人都有帮助。您必须如下所示。onMessageReceived()GCMOverrideonMessageReceived()

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Map<String, String> data = remoteMessage.getData();
    if (null != data && 0 < data.size()) {
        if (data.containsKey("custom_key_1")) {
            sendNotification(data.get("custom_key_1"));
        }
    }
}

private void sendNotification(String messageBody) {
        Intent intent = new Intent(this, DesiredActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_ic_notification)
                .setContentTitle("FCM Message")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
  • 最后但并非最不重要的一点是,我们也可以发送两者。在这种情况下, 当应用程序位于 中时调用 。对于后台和关闭状态,在系统托盘中出现类似于但唯一的区别是我们也可以使用它来将用户重定向到所需的 ,当单击时。下面是这样一个主体的例子。此类主体的示例如下所示。NotificationData PayloadsonMessageReceived()ForegroundNotificationNotification Payloaddata extrasActivityNotificationHTTP POST RequestHTTP POST Request

enter image description here

单击系统托盘上的a时,它将打开和您需要的,以获取并将用户重定向到所需的.下面是代码,您必须编写您的要将用户重定向到所需的.NotificationLauncher ActivityOverrideonCreate()Launcher Activitydata extrasActivityonCreate()ActivityActivity

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(getIntent().hasExtra("custom_key_1") && getIntent().getStringExtra("custom_key_1")
            .equals("custom_value_1")){
        startActivity(new Intent(this, DesiredActivity.class));
        finish();
        return;
    }

    // other operations
}

此类型的另一种情况是,当您的被定义为 在 到达 时,您的在 .因此,当您单击通知时,您必须使用方法才能打开所需的.下面是相同的示例代码。Launcher ActivitylaunchMode="true"manifestNotificationLauncher ActivityForegroundOverrideonNewIntent()Launcher ActivityActivity

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    if (getIntent().hasExtra("custom_key_1") && getIntent().getStringExtra("custom_key_1")
                .equals("custom_value_1")) {
            startActivity(new Intent(this, DesiredActivity.class));
            finish();
    }
}

因此,简而言之,我会说使用Data Payload类型是件好事,因为它提供了更大的灵活性和对它的控制,更重要的是,我们都习惯了,所以这种类型是我们都喜欢的。NotificationGCM

注意:某些设备在后台接收通知时遇到问题,因为我在这里发现了一些查询。此外,当时我正在调查这些情况,我的华硕手机在后台没有收到上述任何类型的通知。所以不确定这些设备有什么问题。


答案 2

我在应用中遇到了同样的问题

这个链接帮助了我:https://developer.android.com/training/notify-user/navigation

您需要做的是在清单中为所需活动定义父活动:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<!-- MainActivity is the parent for ResultActivity -->
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity" />

然后在 onMessageReceived 方法中使用 TaskStackBuilder 创建挂起的意图

// Create an Intent for the activity you want to start
Intent resultIntent = new Intent(this, ResultActivity.class);
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// then use this pending intent to build your notification

推荐