burakk
burakk

Reputation: 1291

How to Apply the Normal Activity Order When the App is Opened from the Notification

Here's my scenario: I have a service that plays the streamed music and creates (and updates) a notification. When pressed on the notification, the user is taken to the B activity.

The structure of my app is A -> B.

When the user goes to home screen with the following flow: B -> A -> Home Screen (the service continues to play music), pressing on the notification takes the user to activity B, but now he cannot go back to activity A. He is taken to the home screen.

I need to implement B -> A order for every situation.

Here are my code snippets:

AndroidManifest.xml:

<activity
    android:name=".ChannelListActivity"
    android:configChanges="locale|keyboard|keyboardHidden|screenLayout|fontScale|uiMode|orientation|screenSize"
    android:launchMode="singleTask" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity
    android:name=".NowPlayingActivity"
    android:parentActivityName=".ChannelListActivity"
    android:launchMode="singleTop" >
</activity>

and the code to create the notification:

Intent intentGoToApp = new Intent(this, NowPlayingActivity.class);
intentGoToApp.putExtra(NowPlayingFragment.EXTRA_CHANNEL_ID, mUserData.getPlayingChannelId());
intentGoToApp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent piGoToApp = PendingIntent.getActivity(getApplicationContext(), 0, intentGoToApp, PendingIntent.FLAG_CANCEL_CURRENT);

So, what do I need to change or add to achieve the behaviour? Thanks in advance...


EDIT: I tried to add the following code, but still not getting the desired result...

Intent intentGoToApp = new Intent(this, NowPlayingActivity.class);
intentGoToApp.putExtra(NowPlayingFragment.EXTRA_CHANNEL_ID, mUserData.getPlayingChannelId());
intentGoToApp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//PendingIntent piGoToApp = PendingIntent.getActivity(getApplicationContext(), 0, intentGoToApp, PendingIntent.FLAG_CANCEL_CURRENT);

Intent intentMainActivity = new Intent(this, ChannelListActivity.class);

PendingIntent piGoToApp = TaskStackBuilder.create(this)
// add all of DetailsActivity's parents to the stack,
// followed by DetailsActivity itself
    .addNextIntentWithParentStack(intentMainActivity)
    .addNextIntentWithParentStack(intentGoToApp)
    .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);*/

Upvotes: 1

Views: 100

Answers (3)

Knossos
Knossos

Reputation: 16038

You need to add Activity A to your backstack so that Android knows the order in which it should exit each Activity.

You might find this official documentation useful.

Beginning in Android 4.1 (API level 16), you can declare the logical parent of each activity by specifying the android:parentActivityName attribute in the <activity> element. This allows the system to facilitate navigation patterns because it can determine the logical Back or Up navigation path with this information.

Upvotes: 1

Konstantin Loginov
Konstantin Loginov

Reputation: 16000

There're few tricks you can do:

  1. Start Activity A in public void onBackPressed() {} of Activity B if Activity B has been started with notification(and finish Activity B);

    public class ActivityB extends Activity {
        static final String ACTION_NOTIFICATION = "ACTION_NOTIFICATION";
        boolean isStartedWithNotification;
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            setIntent(intent);
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ....
        }
    
        // OR onResume() if you don't use fragments
        @Override
        protected void onResumeFragments() {
            super.onResumeFragments();
            handleIntent();
        }
    
        void handleIntent() {
            Intent intent = getIntent();
            if (intent != null && ACTION_NOTIFICATION.equals(intent.getAction())) {
                // handle intent, populate UI based on it's information;
                isStartedWithNotification = true;
                setIntent(null);
            }
        }
    
        @Override
        public void onBackPressed() {
            if (isStartedWithNotification) {
                startActivity(new Intent(this, ActivityA.class)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                finish();
            } else {
                super.onBackPressed();
            }
        }   
    }
    
  2. Instead of starting Activity B via notification - start Activity A to handle intent and immediately start Activity B;

    public class ActivityA extends Activity {
        static final String ACTION_NOTIFICATION = "ACTION_NOTIFICATION";
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            setIntent(intent);
        }
    
        // OR onResume() if you don't use fragments
        @Override
        protected void onResumeFragments() {
            super.onResumeFragments();
            handleIntent();
        }
    
        void handleIntent() {
            Intent intent = getIntent();
            if (intent != null && ACTION_NOTIFICATION.equals(intent.getAction())) {
                setIntent(null);
                //START ACTIVITY B
            }
        }
    }
    

The first approach is more hacky, but with the first one, on low-end devices yours might see "blinking" of Activities' switch. So I'd start with the first one.

I hope, it helps

Upvotes: 1

Grace Coder
Grace Coder

Reputation: 794

Make Activity A as the parent of Activity B by declaring this relationship in the AndroidManifest.xml file so every time the back button is press, the parent activity will be called:

<activity
    android:name=".ActivityB"
    android:label="Activity B"
    android:parentActivityName=".ActivityA">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.yourpackage.MainActivity" />
</activity>

Upvotes: 1

Related Questions