Clicking on notification doesn't open mentioned activity

后端 未结 10 1131
感动是毒
感动是毒 2020-12-09 16:26

I am trying to open an Activity when the notification is clicked and below is my code.

Intent intent = new Intent(this.getApplicationContext(),         


        
相关标签:
10条回答
  • 2020-12-09 16:37

    According to FCM Documentation, for receiving and handling messages,

    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. Your service should override the onMessageReceived callback, which is provided for most message types, with the following exceptions:

    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). 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.

    So Basically, we have two types of Payloads

    1). Notification Payload

    2). Data Payload

    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. In my case, I am using the Postman tool, a Google Chrome Plugin.

    Before making a HTTP Post Request for FCM, you have to consider three things:

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

    2). Request Headers :

    i). Content-Type : application/json

    ii). Authorization : key = YOUR_SERVER_KEY

    Below is the screenshot for the same to show how it looks.

    3). Body : In this we are going to have JSON for Notification and Data Payloads.

    • So starting with Notification Payload, the simplest of all. 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. This is helpful when you don't want to control Notifications by your own and not much data to deal with when Notification comes. You can even control the sound, icon and click_action(only when the app is in Foreground) without writing any code in your onMessageReceived(). One example of a body of such HTTP POST Request is attached in the screenshot below.

    For opening desired Activity when sending click_action parameter, you have to use the below code in your onMessageReceived().

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

    and below is your startActivity() method :

    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. It doesn't even open the Launcher Activity, in case of Background and Closed, if this parameter is specified.

    • Now comes the Data Payload. This is similar to the one we have in 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. Example of a body of such HTTP POST Request is shown below.

    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. You have to Override onMessageReceived() as shown below.

    @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. In this case, onMessageReceived() is called when the app is in Foreground. 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. Below is the example of a body of such HTTP POST Request.Example of a body of such HTTP POST Request is shown below.

    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. Below is the code, you have to write in onCreate() of your Activity to redirect user to the desired 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. So when you click on the Notification, you have to Override the onNewIntent() method in your Launcher Activity to open the desired 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.

    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.

    0 讨论(0)
  • 2020-12-09 16:41

    You have to use FLAG_UPDATE_CURRENT in pendingIntent.

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

    and also pass the same id to notificationManager

     notificationManager.notify(notificationId /* ID of notification */, notificationBuilder.build());
    
    0 讨论(0)
  • 2020-12-09 16:43

    I use this in my 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());
    }
    
    0 讨论(0)
  • 2020-12-09 16:47

    You can specify any Activity to be receiver for push notifications:

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

    So you can add this intent filter in your Activity which you want to open on the click of Push notification.

    0 讨论(0)
  • 2020-12-09 16:48

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

    Post both of these and we might get something useful about what is going wrong under the hood.

    0 讨论(0)
  • 2020-12-09 16:50

    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);
    
    0 讨论(0)
提交回复
热议问题