简体   繁体   English

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

[英]Clicking on notification doesn't open mentioned activity

I am trying to open an Activity when the notification is clicked and below is my code.我试图在点击通知时打开一个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());

Android Manifest:安卓清单:

<?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>

Whenever I get notification from FCM I am calling this notification.每当我收到 FCM 的通知时,我都会调用此通知。 The NotificationActivity is not opening whenever I click on notification, rather the app is opening( splash screen->starting activity of my usual app flow).每当我单击通知时, NotificationActivity都不会打开,而是应用程序正在打开( splash screen->starting activity我通常的应用程序流程的splash screen->starting activity )。 Whenever I get notification while the app is already open, the NotificationActivity is getting opened, but not when app is not already opened.每当我在应用程序已打开时收到通知时, NotificationActivity就会打开,但在应用程序尚未打开时则不会。 Could someone please help me on resolving this?有人可以帮我解决这个问题吗?

Note: Please I am reiterating that NotificationActivity.class is not getting opened when clicked on notification when app is not already opened state.注意:请我重申NotificationActivity.class在应用程序尚未打开状态下单击通知时不会打开。

According to FCM Documentation, for receiving and handling messages,根据FCM文档,用于接收和处理消息,

If you want to receive notifications when your app is in the foreground, you need to add some message handling logic.如果你想在你的应用在前台时收到通知,你需要添加一些消息处理逻辑。

To receive messages, use a service that extends FirebaseMessagingService.要接收消息,请使用扩展 FirebaseMessagingService 的服务。 Your service should override the onMessageReceived callback, which is provided for most message types, with the following exceptions:您的服务应覆盖为大多数消息类型提供的 onMessageReceived 回调,但以下情况除外:

1). 1)。 Notifications delivered when your app is in the background.当您的应用程序在后台时发送的通知。 In this case, the notification is delivered to the device's system tray.在这种情况下,通知将传送到设备的系统托盘。 A user tap on a notification opens the app launcher by default.默认情况下,用户点击通知会打开应用启动器。

2). 2)。 Messages with both notification and data payload, both background and foreground.具有通知和数据有效负载的消息,包括后台和前台。 In this case, the notification is delivered to the device's system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.在这种情况下,通知被传送到设备的系统托盘,数据有效负载被传送到启动器 Activity 的意图的额外内容中。

在此处输入图片说明

So Basically, we have two types of Payloads所以基本上,我们有两种类型的有效载荷

1). 1)。 Notification Payload通知负载

2). 2)。 Data Payload数据负载

3). 3)。 Both (an additional type we can consider).两者(我们可以考虑的附加类型)。

Now let's discuss one by one these payloads.现在让我们一一讨论这些有效载荷。 Before that you need to understand how can you send these Payloads to your app.在此之前,您需要了解如何将这些有效负载发送到您的应用程序。 All you have to do is to make use of any tool that can perform HTTP POST Request .您所要做的就是使用任何可以执行HTTP POST Request工具。 In my case, I am using the Postman tool, a Google Chrome Plugin.就我而言,我使用的是Postman工具,一个 Google Chrome 插件。

Before making a HTTP Post Request for FCM , you have to consider three things:在为FCM发出HTTP Post Request之前,您必须考虑三件事:

1). 1)。 HTTP Post Request URL : https://fcm.googleapis.com/fcm/send HTTP 发布请求网址: https : //fcm.googleapis.com/fcm/send

2). 2)。 Request Headers :请求头:

i).一)。 Content-Type : application/json内容类型:应用程序/json

ii). ii). Authorization : key = YOUR_SERVER_KEY授权:key = YOUR_SERVER_KEY

Below is the screenshot for the same to show how it looks.下面是相同的屏幕截图,以显示它的外观。

在此处输入图片说明

3). 3)。 Body : In this we are going to have JSON for Notification and Data Payloads .正文:在这里,我们将有JSON用于NotificationData Payloads

  • So starting with Notification Payload , the simplest of all.所以从最简单的Notification Payload开始。 In this case, onMessageReceived() is called only when the app is in Foreground , For all other cases, it's a System Tray Notification , which opens the Launcher Activity when clicked.在这种情况下, onMessageReceived()仅在应用程序处于Foreground时调用,对于所有其他情况,它是System Tray Notification ,单击时会打开Launcher Activity This is helpful when you don't want to control Notifications by your own and not much data to deal with when Notification comes.当您不想自己控制Notifications并且在Notification到来时没有太多数据需要处理时,这很有用。 You can even control the sound, icon and click_action(only when the app is in Foreground ) without writing any code in your onMessageReceived() .您甚至可以控制声音、图标和 click_action(仅当应用程序处于Foreground ),而无需在onMessageReceived()编写任何代码。 One example of a body of such HTTP POST Request is attached in the screenshot below.下面的屏幕截图中附有此类HTTP POST Request正文的一个示例。

在此处输入图片说明

For opening desired Activity when sending click_action parameter, you have to use the below code in your onMessageReceived() .要在发送 click_action 参数时打开所需的Activity ,您必须在onMessageReceived()使用以下代码。

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

and below is your startActivity() method :下面是你的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);
}

NOTE : This click_action key will work only when the app is in Foreground, for all other case when the app is in Background and closed, it doesn't work.注意:此click_action键仅在应用程序处于前台时有效,对于所有其他情况,当应用程序处于后台并关闭时,它不起作用。 It doesn't even open the Launcher Activity, in case of Background and Closed, if this parameter is specified.如果指定了此参数,它甚至不会打开 Launcher Activity,在 Background 和 Closed 的情况下。

  • Now comes the Data Payload .现在是数据有效负载 This is similar to the one we have in GCM .这与我们在GCM类似。 This is very important if we want to handle all the Notification stuff by ourselve same as we all were doing in case of GCM .如果我们想自己处理所有Notification东西,就像我们在GCM情况下所做的一样,这非常重要。 Example of a body of such HTTP POST Request is shown below.这种HTTP POST Request的主体示例如下所示。

在此处输入图片说明

So in this case, onMessageReceived() is called everytime and this will work in the same way as that of GCM , so helpful to all of us.所以在这种情况下, onMessageReceived()每次都会被调用,这将与GCM工作方式相同,对我们所有人都有帮助。 You have to Override onMessageReceived() as shown below.您必须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());
}
  • Last but not the least, we can send both Notification and Data Payloads as well.最后但并非最不重要的一点是,我们也可以发送NotificationData Payloads In this case, onMessageReceived() is called when the app is in Foreground .在这种情况下,当应用程序处于Foreground时调用onMessageReceived() For background and closed state, Notification comes in the system tray similar to Notification Payload but the only difference is we can have data extras as well that we can use to redirect user to a desired Activity , when clicked on a Notification .对于后台和关闭状态, Notification出现在系统托盘中,类似于Notification Payload但唯一的区别是我们可以拥有data extras ,当点击Notification时,我们可以用来将用户重定向到所需的Activity Below is the example of a body of such HTTP POST Request .Example of a body of such HTTP POST Request is shown below.下面是这样的主体的示例HTTP POST Request这样的主体的。实施例HTTP POST Request被示出如下。

在此处输入图片说明

When clicking on a Notification on System Tray, it will open the Launcher Activity and You need to Override onCreate() of your Launcher Activity to get the data extras and redirect user to the desired Activity .单击系统托盘上的Notification时,它将打开Launcher Activity ,您需要Override Launcher Activity onCreate()以获取data extras并将用户重定向到所需的Activity Below is the code, you have to write in onCreate() of your Activity to redirect user to the desired Activity .下面是代码,您必须在Activity onCreate()中写入以将用户重定向到所需的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
}

Another case to this type is, when your Launcher Activity is defined as launchMode="true" in the manifest and when the Notification Arrives, your Launcher Activity is in the Foreground .这种类型的另一种情况是,当您的Launcher Activitymanifest定义为launchMode="true"并且Notification到达时,您的Launcher Activity位于Foreground So when you click on the Notification, you have to Override the onNewIntent() method in your Launcher Activity to open the desired Activity .因此,当您单击 Notification 时,您必须Override Launcher ActivityonNewIntent()方法以打开所需的Activity Below is the sample code for the same.下面是相同的示例代码。

@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();
    }
}

So in short, I would say it's good to go with the Data Payload type as it provides more flexibility and control over the Notification and more importantly as we all are used to GCM , so this type is what we all would like to prefer.所以简而言之,我会说使用Data Payload类型很好,因为它提供了更多的灵活性和对Notification控制,更重要的是因为我们都习惯了GCM ,所以这种类型是我们都喜欢的。

Note : Some devices are having issue receiving Notifications in Background as I found some queries over same here.注意:一些设备在后台接收通知时遇到问题,因为我在这里发现了一些查询。 Moreover at the time, I was investigating these cases, my ASUS phone was not receiving notifications in Background for any of the types mentioned above.此外,当时我正在调查这些情况,我的华硕手机没有在后台收到上述任何类型的通知。 So not sure what's the issue with these devices.所以不确定这些设备有什么问题。

I had the same problem in my app我在我的应用程序中遇到了同样的问题

This link helped me: https://developer.android.com/training/notify-user/navigation此链接对我有帮助: https : //developer.android.com/training/notify-user/navigation

What you need to do is define parent activity for your desired activity in Manifest:您需要做的是在清单中为您想要的活动定义父活动:

<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" />

And then use TaskStackBuilder in onMessageReceived method to create pending intent然后在 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

You can specify any Activity to be receiver for push notifications:您可以指定任何Activity作为推送通知的接收者:

<intent-filter>
    <action android:name="PACKAGE_NAME.MESSAGE"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

This intent filter for the activity specifies which activity will be launched in response to push notification ( PACKAGE_NAME is your Android app package)此活动的意图过滤器指定将启动哪个活动以响应推送通知( PACKAGE_NAME是您的 Android 应用程序包)

So you can add this intent filter in your Activity which you want to open on the click of Push notification.因此,您可以在您想要点击推送通知时打开的Activity添加此意图过滤器。

You have to use FLAG_UPDATE_CURRENT in pendingIntent.您必须在FLAG_UPDATE_CURRENT中使用FLAG_UPDATE_CURRENT

PendingIntent pendingIntent = PendingIntent.getActivity(this, notificationId /* Request code */, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

and also pass the same id to notificationManager并将相同的 id 传递给notificationManager

 notificationManager.notify(notificationId /* ID of notification */, notificationBuilder.build());

If you read the firebase docs in detail, there are two types of payloads如果您详细阅读了 firebase 文档,则有两种类型的有效载荷

  • Data payload数据有效载荷
  • Notification payload通知负载

The data payload triggers the onMessageReceived() callback when app is both foreground and background.当应用程序同时处于前台和后台时,数据负载会触发onMessageReceived()回调。 This is not the case with notification payload, which triggers the callback in only foreground state.通知负载不是这种情况,它仅在前台状态触发回调。 So, if you use the data payload this problem should be solved.所以,如果你使用数据有效载荷,这个问题应该可以解决。

Check this code and let me know.检查此代码并告诉我。

        Intent intent = new Intent(this, LoginActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

Thats the intented behaviour.这就是故意的行为。 If your app is in background, notification is created by android system which does not have your pendingIntent action.So it does not work.如果您的应用程序在后台,则通知是由没有您的 pendingIntent 操作的 android 系统创建的。因此它不起作用。 In the foreground case it works because notification is created by your code.在前台情况下,它可以工作,因为通知是由您的代码创建的。

Please check the doc in the below link.请查看以下链接中的文档。 https://firebase.google.com/docs/notifications/android/console-device#receive_and_handle_messages https://firebase.google.com/docs/notifications/android/console-device#receive_and_handle_messages

Sorry not to add a comment as I'm a fairly new comer.很抱歉没有添加评论,因为我是一个相当新的人。

You can just do the following two things for further investigating:你可以做以下两件事来进一步调查:

  1. After the notification has been created, use shell command "adb shell dumpsys activity i [your package name]" to see your notification in detail, to confirm it is really what you want.创建通知后,使用 shell 命令“adb shell dumpsys activity i [your package name]”详细查看您的通知,以确认它确实是您想要的。 Remember to replace "[your package name]" with your own package name;记得把“[你的包名]”替换成你自己的包名;

  2. Tracking the event log during the time you are reproducing this using "adb logcat -v threadtime -b events".在使用“adb logcat -v threadtime -b events”重现此事件期间跟踪事件日志。

Post both of these and we might get something useful about what is going wrong under the hood.发布这两篇文章,我们可能会得到一些有用的信息,了解幕后出了什么问题。

Set your pending intent like below设置您的待定意图,如下所示

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

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

add it to your notification using使用它添加到您的通知

.setContentIntent(pendingIntent);

I use this in my FirebaseMessagingService:我在 FirebaseMessagingService 中使用它:

/**
 * Create and show a simple notification containing the received FCM message.
 *
 * @param messageBody FCM message body received.
 */
private void sendNotification(String title, String messageBody, String data) {
    Intent intent = new Intent(this, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(getApplicationContext())
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

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

    notificationManager.notify(id++ /* ID of notification */, notificationBuilder.build());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 点击通知后,新活动将无法开始 - Upon clicking notification, new activity doesn't start 如何通过单击通知打开带有进度的活动 - How to open an activity with its progress by clicking on the notification 单击Firebase Notification时,打开MainActivity以外的其他活动 - Open a different activity other than MainActivity when clicking Firebase Notification 单击通知时如何打开MainActivity以外的其他活动 - How to open another activity other than the MainActivity when clicking on notification 当我点击通知推送时,特定活动无法打开(需要真正的帮助) - When i push notification clicked, specific activity doesn't open (need really help) 如何打开新活动并通过单击Firebase通知在textview上打印通知消息 - How open a new activity & print the notification message on a textview by clicking on firebase notification 通过单击信息窗口打开活动 - Open Activity by clicking on InfoWindow Android gcm通知无法打开应用程序 - Android gcm notification doesn't open application 单击通知时启动活动 - Start an Activity when clicking a notification 如何通过点击通知去活动? - How to go to an activity by clicking on notification?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM