Reputation: 1291
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
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
Reputation: 16000
There're few tricks you can do:
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();
}
}
}
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
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