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

ric*_*ick 25 java android push-notification firebase-cloud-messaging firebase-notifications

我试图在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());
Run Code Online (Sandbox Code Playgroud)

Android清单:

<?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>
Run Code Online (Sandbox Code Playgroud)

每当我收到来自FCM的通知时,我都会调用此通知.该NotificationActivity是不开放每当我点击的通知,而应用程序被打开(splash screen->starting activity我平时的应用程序流量).每当我在应用程序已经打开时收到通知时,它NotificationActivity就会被打开,但是当应用程序尚未打开时却没有.有人可以帮我解决这个问题吗?

注意:请重申,NotificationActivity.class当app尚未打开状态时单击通知时,不会打开.

Muk*_*ana 26

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

如果您希望在应用程序位于前台时收到通知,则需要添加一些消息处理逻辑.

要接收消息,请使用扩展FirebaseMessagingService的服务.您的服务应覆盖为大多数消息类型提供的onMessageReceived回调,但以下情况除外:

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

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

在此输入图像描述

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

1).通知有效载荷

2).数据有效载荷

3).两者(我们可以考虑的另一种类型).

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

制作之前HTTP Post RequestFCM,你必须要考虑三件事情:

1).HTTP Post Request URL: https ://fcm.googleapis.com/fcm/send

2).请求标题:

一世).Content-Type:application/json

ⅱ).授权:key = YOUR_SERVER_KEY

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

在此输入图像描述

3).正文:在这一点,我们将不得不JSONNotificationData Payloads.

  • 所以从Notification Payload开始,这是最简单的.在这种情况下, onMessageReceived()仅在应用程序进入时才会调用Foreground,对于所有其他情况,它是a System Tray Notification,Launcher Activity在单击时打开.当你不想自己控制Notifications而没有太多数据来处理时,这很有用Notification.您甚至可以控制声音,图标和click_action(仅在应用程序进入时Foreground),而无需在您的代码中编写任何代码onMessageReceived().HTTP POST Request下面的屏幕截图中附有一个这样的身体的一个例子.

在此输入图像描述

Activity在发送click_action参数时打开所需的内容,您必须使用以下代码onMessageReceived().

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

以下是你的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);
}
Run Code Online (Sandbox Code Playgroud)

注意:此click_action密钥仅在应用程序位于Foreground时才有效,对于所有其他情况,当应用程序处于Background并关闭时,它不起作用.如果指定了此参数,它甚至不会在后台和关闭的情况下打开启动器活动.

  • 现在来了Data Payload.这与我们的相似GCM.这是非常重要的,如果我们想要处理所有的Notification东西,就像我们所做的那样GCM.这种物体的例子HTTP POST Request如下所示.

在此输入图像描述

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

@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());
}
Run Code Online (Sandbox Code Playgroud)
  • 最后但并非最不重要的,我们可以同时发送NotificationData Payloads为好.在这种情况下,onMessageReceived()在应用程序进入时调用Foreground.对于背景和关闭状态,Notification进入类似的系统托盘,Notification Payload但唯一的区别是data extras我们可以使用,我们可以用来将用户重定向到所需的Activity,当点击一个Notification.下面是这样的身体的例子.这样HTTP POST Request的身体的例子HTTP POST Request如下所示.

在此输入图像描述

当在点击NotificationSystem Tray上,它会打开Launcher Activity,你需要Override onCreate()你的Launcher Activity获取data extras和重定向用户所需Activity.下面是代码,你必须写onCreate()你的Activity用户重定向到所期望的Activity.

@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
}
Run Code Online (Sandbox Code Playgroud)

这种类型的另一种情况是,当你Launcher Activity被定义为launchMode="true"manifestNotification到达时,你Launcher Activity是在Foreground.因此,当您单击通知时,您必须在您OverrideonNewIntent()方法中Launcher Activity打开所需的方法Activity.下面是相同的示例代码.

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

所以简而言之,我认为采用Data Payload类型是好的,因为它提供了更多的灵活性和控制权Notification,更重要的是我们都习惯了GCM,所以这种类型是我们都希望的.

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


小智 1

您可以指定任何一个Activity作为推送通知的接收者:

<intent-filter>
    <action android:name="PACKAGE_NAME.MESSAGE"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
Run Code Online (Sandbox Code Playgroud)

该活动的意图过滤器指定将启动哪个活动来响应推送通知(PACKAGE_NAME是您的 Android 应用程序包)

因此,您可以在您Activity想要单击推送通知时打开的意图过滤器中添加此意图过滤器。