4

I've got an activity that I launch from a notification. I include a back-stack using TaskStackBuilder so that when the user hits the home button (actionbar title button) or uses the back key, it will return to the application. However, it isn't working in that manner, instead hitting back or the actionbar title button always results in the app closing.

For what it's worth, my project structure is organized such that all UI components are in an Android Library (com.be.commotion) and an outside "wrapper" project uses that Library.

Here's how I build the notification:

// This is the activity that will be launched when tapping the notification
Intent intentNotification = new Intent(this, NowPlaying.class);
intentNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

// Create the back stack so the user can get back to the main activity when pressing the back button
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(NowPlaying.class);
stackBuilder.addNextIntent(intentNotification);
PendingIntent pendingNowPlayingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

// Setup the custom notification view
RemoteViews notificationContent = new RemoteViews(getPackageName(), R.layout.notification_now_playing);
....

// Setup the intent that will play/stop music when the stop button is tapped
Intent musicControlIntent = new Intent(this, CommotionMediaPlayer.class);

PendingIntent musicPendingIntent = PendingIntent.getService(this, 0, musicControlIntent, PendingIntent.FLAG_UPDATE_CURRENT);

notificationContent.setOnClickPendingIntent(R.id.ibMediaControl, musicPendingIntent);

// Update the notification with this info
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.ic_launcher)
                    .setContentTitle(song.text)
                    .setContentText(song.artist)
                    .setContentIntent(pendingNowPlayingIntent)
                    .setLargeIcon(artwork)
                    .setContent(notificationContent)
                    .setOngoing(true);

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

// Using the nowPlayingNotificationId allows the notification to be updated with later calls instead of causing a new notification to show up
mNotificationManager.notify(nowPlayingNotificationId, builder.build());

Here's the applicable definitions in my AndroidManifest.xml (for the wrapper project):

    <activity android:name="com.be.commotion.ui.StartupActivity"
            android:label="@string/app_name"
            android:noHistory="true"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Holo.NoActionBar" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

    <activity android:name="com.be.commotion.ui.NowPlaying"
              android:label="Now Playing"
              android:parentActivityName="com.be.commotion.ui.StartupActivity"
              android:screenOrientation="portrait">

        <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.be.commotion.ui.StartupActivity" />

    </activity>
bugfixr
  • 7,997
  • 18
  • 91
  • 144
  • Why the action bar button is doing it, I don't know - and don't see any code for it here. But I'd like to point out that what you want to do with the back button goes against the Android flow, and will hinder the User Experience. The back button is supposed to go back to where the user was before. Bringing them to the main activity means that they're going forward instead of back. – Navarr Jul 16 '13 at 13:37
  • Additionally, it sounds like you're using the Home button to trigger a "back" when you should have the home button launching either the MainActivity or the ParentActivity (which is not always supposed to be back) – Navarr Jul 16 '13 at 13:38
  • @Navarr - thanks for your comment... I'm not sure I agree with your statement re: the back button. If I use the Gmail app and open an email from my notification bar, pressing the back button takes me out of the email and shows me the inbox view. That feels natural to me and is what I want to achieve with my app. – bugfixr Jul 16 '13 at 13:48
  • As per back key, why not simply override `onBackPressed()` in `NowPlaying` and launch `StartupActivity`? – ozbek Jul 16 '13 at 15:27
  • @bugfixrWere u able to solve that ? I have the same problem, and I am searching since yesterday. As per all the help given on the stackoverflow, I am doing the same as you. But unable to solve. Can you help me plz – Gaurav Arora May 10 '16 at 16:52

3 Answers3

3

You can do it by 2 step without using TaskStackBuilder
1/ set Flag for your Intent

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);

2/set Flag for your PendingIntent

pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_CANCEL_CURRENT);

It works for me, good luck guys

  • Need suggestion. All are right but when i click device back button and out from the application click event(Play/Pause/Forward/Close) button doesn't work.Please help me. – Helal Khan Mar 11 '14 at 13:47
  • this will only solve the issue if the user opens the notification while the app is running. – Mohamed Nageh Apr 02 '19 at 19:06
  • @MohamedNageh I agree. Only works if the app is running. Any idea on how to make it generic? – tsik Jan 07 '21 at 14:49
  • agreed luck is needed here, cause this doesn't work if the app isn't running – Oush Mar 01 '21 at 16:52
2

Add the main activity to the stack before you add the desired activity(the activity directly called when notification is clicked). Eg:

stackBuilder.addNextIntent(new Intent(this,MainActivity.class));
stackBuilder.addNextIntent(new Intent(this,DesiredActivity.class));
Manan Sheth
  • 191
  • 2
  • 11
0

Maybe we are solving a slightly different problem but it boils down to the same issue. For us the solution was to use:

startActivityForResult(intent, 0);

What we wanted to do is to have a notification that takes to Activity B and, when the back button is clicked, to take us to Activity A

There are two ways to do that:

Start A from B: Works if all activities are in your app

  1. Send a parameter in the notification bundle to define that the activity was started from a notification
  2. Override the OnBack of activity B and make it start activity A with a CLEAR_TOP flag (so that the back does not take back to B)

Start B from A: Works for activities in different apps (e.g. opening an email client)

  1. Make the notification to take to Activity A (pass the necessary parameters to know that the activity was started from a notification)
  2. Start activity B (e.g. the email client) with a startActivityForResult. If you use the normal startActivity the "back" button will not work.
Dharman
  • 30,962
  • 25
  • 85
  • 135
tsik
  • 609
  • 8
  • 10