Search code examples
android-intentandroid-activityalarmmanagerandroid-pendingintentlocalnotification

OnNotification click listener


My Android app has local notifications implemented using the Alarm Manager. The app flow is as follows: SplashActivity > BiometricActivity > ProfileActivity > MainActivity > DetailedActivity. When the DetailedActivity is resumed, the app sets an alarm for 30 seconds later and sends it to the AlarmBroadcast class through a pending intent. The Alarm Broadcast receives the intent, sets up a pending intent to the NotificationActivity class, creates a notification, and sends it.

I am trying to implement three scenarios:

If the app is open and the user has passed the BiometricActivity, the NotificationActivity should be opened.

If the app is running in the background, it should come to the front and open the NotificationActivity if the user has passed the BiometricActivity, otherwise, it should open the BiometricActivity first and then show the NotificationActivity upon success.

If the app is closed, it should start and open the NotificationActivity when the notification is clicked. I am having trouble implementing the onNotificationClickListener and am limited to setting only one activity in the Pending Intent in the OnReceive method of the AlarmBroadcast class. I have been stuck on this for two days and would appreciate any suggestions for a solution.(API 32)

Thanks

As far as notification is concerned, they are working fine but always NotificationActivity shows up on notification click. I want to implement different scenarios (mentioned above) but I can only send pending intent to one Activity. I can detect if app is running or not in alarm receiver and set pending intent accordingly. But app state can be changed by the time user clicks on notification


Solution

  • Generally speaking, your best bet is to have the Notification launch a "dispatcher" Activity. The "dispatcher" then has to figure out what the current state of the app is, and redirect the user accordingly.

    If the app was in the foreground, the "dispatcher" Activity will be launched on top of the current state of the app.

    If the app was in the background, it will be brought forward in whatever state it was in and the "dispatcher" Activity will be launched on top of that.

    If the app wasn't running at all, Android will create a new task for the app and launch the "dispatcher" Activity into this task.

    In all cases, the "dispatcher" Activity should evaluate the state of the app (ie: is the user logged in or not, etc.) in onCreate() and then redirect the user immediately to the appropriate Activity, by calling startActivity() with an Intent with the correct class and flags (FLAG_ACTIVITY_SINGLE_TOP, FLAG_ACTIVITY_CLEAR_TOP, FLAG_ACTIVITY_CLEAR_TASK, etc.) depending on the state. The "dispatcher" Activity doesn't need to have any UI, as it is short-lived (finishes in onCreate()).

    The "dispatcher" Activity should have the following set in its manifest declaration:

    android:noHistory="true"
    android:excludeFromRecents="true"
    

    These attributes will ensure that another launch of the app from the HOME screen will not launch the "dispatcher" Activity and that if the user resumes the task from the list of recent tasks, Android will also not resume the task by launching the "dispatcher" Activity.

    The "dispatcher" Activity can determine if it is the only Activity in the task by checking the value returned by isTaskRoot().