Android: Show Staus Bar Notificationacion only when exiting the app

I have an application that contains four actions. In the application, the user will constantly move through 4 actions. The app also has a running service in the background, the service displays status bar notifications and listens for content changes to be displayed in the notification.

The service currently displays a notification whenever the user triggers an activity that requires a notification to be shown, so the notification is displayed even if you are still using the app. The desired scenario is to show the notification only when the user navigated out of the app.

I tried to override lifecycle methods like this:

    @Override
protected void onPause() {  
    Intent intent = new Intent();
    intent.setAction(MyService.ACTION_DISPLAY_PENDING_NOTIFICATION);
    sendBroadcast(intent);
    super.onPause();
}

@Override
protected void onResume() { 
    super.onResume();
    Intent intent = new Intent();
    intent.setAction(MyService.ACTION_CANCEL_NOTIFICATION);
    sendBroadcast(intent);      
}

      

And the service will look like this:

@Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (action.equals(ACTION_DISPLAY_PENDING_NOTIFICATION)) {
            showNotification();
        }

        else if (action.equals(ACTION_CANCEL_NOTIFICATION)) {
            mNotificationManager.cancel(mNotId);
        }
    }

      

It works. But since the intent is sent anytime the user navigates away from the activity , I experience unwanted behavior and little performance when the user navigates through 4 activities. The service will try to display a notification even when moving from Activity A to Activiy B or any combination within 4 actions.

The notification is canceled immediately because when a new activity B starts, it calls mNotificationManager.cancel (mNotifId) during onResume , but the notification was built and shown for a split second as the service was told to do so when exiting Activity A. This is the behavior to which I want to contact, instead of creating and showing these notifications unnecessarily,

Is there a way to know when a user leaves this activity in another application , i.e. the home page, etc .; but not in the application itself?

EDIT

To clarify, there are two things that would need to be checked during the onPause method,

a) Are there previous activities in the foreground? What for? As the user can navigate away from the activity by pushing back, which means the last activity on the stack will be displayed. To test this, the answer from DennisDrew will work, we can test it like this:

if(!ForegroundHelper.activityExistsInForeground()){
//show your notification
}

      

But this is not the only way the user could navigate out of the action, the user can also press the HomeKey, in which case, if activityExistsInForeground()

evaluates to true or false, the notification should be displayed.

b) Is the user navigating to another activity in the application? For example, the user is in activity A, A is now a foreground only activity , the user clicks on the UI element that launches Activity B. Despite activityExistsInForeground()

evaluating to false, the user not leaving the app launches a new instance of the activity. which was not previously on freground.

I tried to add flags like private boolean launchingNewActivity = false

defaults and set a flag true

when I know I am going to another action, for example when I click an item in my list:

litview.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            launchingNewActivity = true
            startActivity2(arg2);
        }           
    });

      

and then checking this during onPause:

@Override
protected void onPause() {
    if(!ForegroundHelper.activityExistsInForeground() && launchingNewActivity){
    //show your notification        
}

      

But by doing this, it never shows a notification, since double check is always false by default.

+3


source to share


2 answers


What if you used a singleton link? You can create a class like:

public static class ForegroundHelper {
    public static boolean[] activityStates = new boolean{false, false, false, false};
    public static final int ACTIVITY_A = 0;
    public static final int ACTIVITY_B = 1;
    public static final int ACTIVITY_C = 2;
    public static final int ACTIVITY_D = 3;

    public static boolean activityExistsInForeground(){
        for(boolean b : activityStates){
            if(b)
                return true;
        }

        return false;
    }
}

      

Then, in each action, onResume () do:

//For your first activity (Activity A)
ForegroundHelper.activityStates[ForegroundHelper.ACTIVITY_A] = true;

      

And in each action onPause () do:



ForegroundHelper.activityStates[ForegroundHelper.ACTIVITY_A] = false;

      

And then, in the onStop () of each activity, do:

if(!ForegroundHelper.activityExistsInForeground()){
    //show your notification
}

      

By the way, I've never done anything like this, so I have no idea if it will work exactly the same as I coded it ... but let me know if that helps.

+3


source


What I did for this was that I extended the application class and kept the "topActivity" there, which I would set in each onResume / onPause method, for example:

public class myApp extends Application{

   private Activity topActivity;
}

      

Now in every action



@Override
protected void onResume() {

((myApp) getApplication()).setOnTopActivity(this);
}

@Override
    protected void onPause() {
        ((myApp) getApplication()).setOnTopActivity(null);
        super.onPause();
    }

      

Thus, when the app is not visible, topActivity is NULL. So, before showing your notification, just check if topActivity == null . If so, your app is not in the foreground, you can show your notification.

If you don't have access to your application class, you can always store this value in a static way :)

+2


source







All Articles