TimSim
TimSim

Reputation: 4036

Android - Overriding ActionBar back and device back button

In my app I have a MainActivity and a TimerActivity. In normal circumstances in TimerActivity the device back button and the ActionBar's up button work as they should - they lead from the TimerActivity to the MainActivity. But when I open the TimerActivity by clicking on my app's notification, the back buttons lead to the home screen instead of the MainActivity. I would like both back buttons (device and ActionBar's up button) to always open the MainActivity - unless of course the user is in the MainActivity in which case the back button should close the MainActivity. This is how Gmail and Google Drive apps work when you open an activity through a notification and it makes the most sense.

Here's how my notification opens the activity:

Notification timerNotification;

mBuilder = new NotificationCompat.Builder(getApplicationContext())
    .setSmallIcon(ongoingNotificationIcon)
    .setContentTitle(ongoingNotificationContentTitle)
    .setContentText(ongoingNotificationContentText)
    .setTicker(ongoingNotificationTicker)
    .setPriority(99)
    .setOngoing(true);

Intent resultIntent = new Intent(this, TimerActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(
        this, 0, resultIntent, PendingIntent.FLAG_CANCEL_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
timerNotification = mBuilder.build();

startForeground(MyApplication.NOTIFICATION_ID, timerNotification);

I tried overriding the back button in TimerActivity like this:

public void onBackPressed() {    
    Intent intent_main = new Intent(getApplicationContext(), MainActivity.class);
    startActivity(intent_main);
}

But then pressing the back button again on the MainActivity returns the user to the TimerActivity (so the user is in a loop) instead of exiting the app which is the desired behavior. Also, onBackPressed() doesn't affect the ActionBar's up button.

Upvotes: 0

Views: 3712

Answers (3)

smoothBlue
smoothBlue

Reputation: 203

  1. To override Actionbar Up button, use:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
    {
        switch(item.getItemId()) {
            case android.R.id.home:
                //User clicked home, do whatever you want
                return true;
            default:        
                return super.onOptionsItemSelected(item);
        }
    }
    
  2. To auto return to previous activity, please specify previous activity in AndroidManifest.xml:

    <activity
        android:name=".SecondActivity"              
        android:label="@string/label_myLabel"
        android:parentActivityName=".FirstActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.yourpackage.FirstActivity"/>
    </activity>
    

Upvotes: 3

ianhanniballake
ianhanniballake

Reputation: 200020

As explained in the Notifications Setting up a regular activity PendingIntent, you should use TaskStackBuilder to build a synthetic back stack so that your back button functions as if the user had navigated to their normally:

...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
    stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());

The Action Bar Up action, as you noticed, does not differ whether you are coming from a notification or not (as expected if you've set it up correctly).

Upvotes: 0

adneal
adneal

Reputation: 30804

onBackPressed() doesn't affect the ActionBar's up button.

The "back" button and the "up" button are two different means of navigation.

From the docs:

Up

The Up button is used to navigate within an app based on the hierarchical relationships between screens.

Back

The system Back button is used to navigate, in reverse chronological order, through the history of screens the user has recently worked with. It is generally based on the temporal relationships between screens, rather than the app's hierarchy.

So, what you're describing as your problem is actually the recommended way to navigate through your app.

Nevertheless, if you want your users to go to your MainActivity from your TimerActivity after pressing your Notification, the easiest way to implement that would be to include an Intent extra to check when you're launching the Activity from your Notification.

Here's an example:

Intent resultIntent = new Intent(this, TimerActivity.class);
resultIntent.putExtra("fromNotification", true);

In your TimerActivity

private boolean mFromNotification;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final Bundle args = getIntent().getExtras();
    if (args != null) {
        mFromNotification = args.getBoolean("fromNotification");
    }
}

@Override
public void onBackPressed() {
    if (mFromNotification) {
        startActivity(new Intent(this, MainActivity.class));
        finish();
    } else {
        super.onBackPressed();
    }
}

Upvotes: 2

Related Questions