Search code examples
androidandroid-intentnotificationsandroid-pendingintent

Trigger Method in Activity when Notification is tapped


My app repeatedly loads data from a server. Among those data are messages.
Whenever new messages are loaded, the MainActivity is called on an Interface's callback method onMessagesReceived(int numOfMessages).
The app has only one Activity and every screen is implemented as a Fragment. Switching of Fragments is managed by a dedicated Navigator class.

My problem is the handling of the user tapping on the Notification. When the user taps on the Notification, the message list should be shown.

public class MainActivity extends AppCompatActivity implements MessageListener {
    private static final int MESSAGE_NOTIFICATION_ID = 101010;
    private static final String EXTRA_SHOW_MESSAGES = "SHOW_MESSAGES";

    private Navigator mNavigator;

    @Override
    onMessagesReceived(int numOfMessages) {
        Intent intent = new Intent(this, MainActivity.class);
        testIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        testIntent.putExtra(EXTRA_SHOW_MESSAGES, true);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "testChannel")
                .setSmallIcon(R.drawable.ic_message_notification)
                .setContentTitle("New messages!")
                .setContentText("You got " + numOfMessages + " new messages")
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setContentIntent(pendingIntent);

        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        notificationManager.notify(MESSAGE_NOTIFICATION_ID, builder.build());
    }

    @Override
    protected void onResume() {
        super.onResume();

        Bundle extras = getIntent().getExtras();
        if (extras != null && extras.containsKey(EXTRA_SHOW_MESSAGES)) {
            if (extras.getBoolean(EXTRA_SHOW_MESSAGES)) {
                mNavigator.openMessageList();
            }
        }
    }
}

At the moment, the MainActivity shows up, when the app is in background, but in onResume, the Bundle returns as null.
When the app is in the foreground, nothing happens at all.

I want to achieve on a click on the Notification:
- When the user is inside the app, the MessageList Fragment should be opened
- When the user is not inside the app, it should be started before opening the MessageList Fragment

Can someone give me a hint, how to proceed from here? Maybe using Intents isn't the right solution here?


Solution

  • After some more digging on Intents and Notifications, I finally came up with a solution.

    public class MainActivity extends AppCompatActivity implements MessageListener {
        private static final int MESSAGE_NOTIFICATION_ID = 101010;
        private static final String EXTRA_SHOW_MESSAGES = "SHOW_MESSAGES";
    
        private Navigator mNavigator;
    
        @Override
        onMessagesReceived(int numOfMessages) {
            Intent intent = new Intent(this, MainActivity.class);
            testIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
            testIntent.putExtra(EXTRA_SHOW_MESSAGES, true);
    
            PendingIntent pendingIntent = PendingIntent.getActivity(
                this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "testChannel")
                    .setSmallIcon(R.drawable.ic_message_notification)
                    .setContentTitle("New messages!")
                    .setContentText("You got " + numOfMessages + " new messages")
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setContentIntent(pendingIntent);
    
            NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
            notificationManager.notify(MESSAGE_NOTIFICATION_ID, builder.build());
        }
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            this.setIntent(intetnt)
    
            Bundle extras = intent.getExtras();
            if (extras != null && extras.containsKey(EXTRA_SHOW_MESSAGES)) {
                if (extras.getBoolean(EXTRA_SHOW_MESSAGES)) {
                    mNavigator.openMessageList();
                }
            }
        }
    }
    

    I moved my code, reading the new Intent, to onNewIntent. This method gets called, when an Activity gets a new Intent and before onResume. This triggers regardless of the Activity being in the foreground or not. I also set this new Intent to be the Activities Intent with setIntent, otherwise the Intent that initialy started my Activity, is called by getIntent().