TaskStackBuilder not working - android

I am trying to create synthetic stack but it is not working.
Here is my code.
Intent resultIntent = new Intent(context, NotificationListScreen.class);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack
stackBuilder.addParentStack(NotificationListScreen.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);
// Puts the PendingIntent into the notification builder
builder.setContentIntent(resultPendingIntent);
// Kills the notification when user clicks on it
builder.setAutoCancel(true);
Manifest Entry
<activity
android:name=".modules.notification.NotificationListScreen"
android:screenOrientation="portrait" android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/title_activity_notification_list_screen"
android:parentActivityName=".modules.splash.SplashScreen">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".modules.splash.SplashScreen"/>>
I went through this Android - Build a notification, TaskStackBuilder.addParentStack not working for trouble shooting.

Related

Unable to create back stack for activities

I am receiving a notification and i want to create a custom back stack so the user can navigate through it.But as of now clicking on the notification opens the desired activity but when i press the back button it completely exits the app.
Intent resultIntent = new Intent(this, NotifViewActivity.class);
resultIntent.putExtra(StringHolder.NOTIFICATION_ID, notif.getId());
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(HomeActivity.class);
stackBuilder.addParentStack(NotifActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationCompat = new NotificationCompat.Builder(context)
.setAutoCancel(true)
.setContentTitle(notif.getTitle())
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(resultPendingIntent);
Manifest File
<activity
android:name=".NotifActivity"
android:parentActivityName=".HomeActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name=".NotifViewActivity"
android:parentActivityName=".NotifActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".NotifActivity" />
</activity>
The way i want it to work is,on click of the notification the user is taken to
NotifViewActivity then when back button is pressed the user is taken to NotifActivity and when back button is pressed again the user is taken to
HomeActivity .Thats the hierarchy i am trying to create,how can i do that?
You should build your task stack that way:
stackBuilder.addParentStack(HomeActivity.class);
stackBuilder.addParentStack(NotifActivity.class);
stackBuilder.addNextIntentWithParentStack(resultIntent);
Or actually because you already specifying activity hierarchy in manifest, you can do it with just one line:
stackBuilder.addNextIntentWithParentStack(resultIntent);
Or another way to archive the same without specifying hierarchy in manifest:
Intent mainActivityIntent = new Intent(this, HomeActivity.class);
Intent notifActivityIntent = new Intent(this, NotifActivity.class);
stackBuilder.addNextIntent(mainActivityIntent);
stackBuilder.addNextIntent(notifActivityIntent);
stackBuilder.addNextIntent(resultIntent);
For anyone who is trying to start those the created activity with TaskStackBuilder, follow #Divers solution and then use taskStackBuilder.startActivities().
try this :
put below code into NotifViewActivity
#Override
public void onBackPressed() {
Intent i = new Intent(this, HomeActivity.class);
i.putExtra("exit", true);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
super.onBackPressed();
}

Opening application from notification

Let's say that we have Activity which displays funny picture and name it FunnyActivity. This Activity can be launched from MainActivity, which is base Activity in out application, after clicking button. We want also to push some notifications sometimes and when user clicks on notification this FunnyActivity should be launched. So we add this part of code:
Intent notificationIntent = new Intent(this, FunnyActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent intent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), notificationIntent, 0);
and this PendingIntent is using in notification builder
setContentIntent(intent)
Of course FunnyActivity is beautifully launching, but we want to open MainActivity when user clicks back button on FunnyActivity.
How can we achieve that? Please remember that when user came back to MainActivity he can open FunnyActivity again from button.
Try this:
// Intent for the activity to open when user selects the notification
Intent detailsIntent = new Intent(this, DetailsActivity.class);
// Use TaskStackBuilder to build the back stack and get the PendingIntent
PendingIntent pendingIntent =
TaskStackBuilder.create(this)
// add all of DetailsActivity's parents to the stack,
// followed by DetailsActivity itself
.addNextIntentWithParentStack(upIntent)
.addNextIntent(detailsIntent);
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(pendingIntent);
Source: Create back stack when starting the activity
You can try this:
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
Intent resultIntent = new Intent(this, FunnyActivity.class);
// Adds the back stack
stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
Intent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)/*.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))*/
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(msg)
.setContentIntent(resultPendingIntent)
.setAutoCancel(true);
This is how you can achieve solution to your problem. Hope this helps you

Get back to previous Activity when Ongoing notification is clicked

I'm having an activity with some EditTexts and an Ongoing Notification.
After filling into EditTexts, I come back Home screen by pressing Home button (my app is running in background). All I want is to come back my activity with filled EditTexts (not to create a new one) when I click the Ongoing Notification.
I have tried this
How should i do from notification back to activity without new intent
And this
Notification click: activity already open
They don't work at all !!!
Below is my code snippet
ProtocolMonitorActivity.java
Intent resultIntent = new Intent(this, ProtocolMonitorActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(ProtocolMonitorActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notiBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.noti_icon)
.setContentTitle("Protocol Monitor App")
.setContentText("Service is running")
.setOngoing(true);
notiBuilder.setContentIntent(resultPendingIntent);
notiManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notiManager.notify(notiId, notiBuilder.build());
Manifest
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".ProtocolMonitorActivity"
android:label="#string/app_name"
android:process="com.android.phone"
android:launchMode="singleTop"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEVELOPMENT_PREFERENCE" />
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ProtocolMonitorActivity" />
</activity>
</application>
Does someone have any idea on this?
Thank you so so much!!!
You cannot do this using TaskStackBuilder. The behaviour of TaskStackBuilder is that it always clears the task (recreating any activites).
You just need a "launch Intent" to bring your task to the foreground in whatever state it happens to be in. There's 2 ways to do this:
Varient 1:
final Intent notificationIntent = new Intent(this, ProtocolMonitorActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Variant 2:
final Intent notificationIntent =
PackageManager.getLaunchIntentForPackage(getPackageName());
Then do:
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notiBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.noti_icon)
.setContentTitle("Protocol Monitor App")
.setContentText("Service is running")
.setOngoing(true);
notiBuilder.setContentIntent(resultPendingIntent);
notiManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notiManager.notify(notiId, notiBuilder.build());
Just insert this line
resultIntent.setAction(Intent.ACTION_MAIN);
set android:launchMode="singleTop" in your activity tag in menifest inside required activity.

Why do we use the TaskStackBuilder?

Why do we use the TaskStackBuilder when creating a notification? I do not get the logic behind it.
Can someone please explain.
public void showText(final String text){
Intent intent = new Intent (this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(intent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(getString(R.string.app_name))
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_VIBRATE)
.setContentIntent(pendingIntent)
.setContentText(text)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICACTION_ID, notification);
}
Suppose you have an email sending app and you have two activities in it. One is MainActivity which has the email list and other one is for displaying an email (EmailViewActivity). So now when you receive a new email you display a notification on statusbar. And now you want to view that email when a user clicks on it and also after displaying the email if the user clicks back button you want to show the email list activity(MainActivity). For this scenario we can use TaskStackBuilder. See below example:
public void showEmail(final String text){
Intent intent = new Intent (this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(intent);
Intent intentEmailView = new Intent (this, EmailViewActivity.class);
intentEmailView.putExtra("EmailId","you can Pass emailId here");
stackBuilder.addNextIntent(intentEmailView);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(getString(R.string.app_name))
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_VIBRATE)
.setContentIntent(pendingIntent)
.setContentText(text)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICACTION_ID, notification);
}
Hope you can understand.
Follow below urls for more details:
http://developer.android.com/reference/android/support/v4/app/TaskStackBuilder.html
http://developer.android.com/guide/components/tasks-and-back-stack.html
http://www.programcreek.com/java-api-examples/index.php?api=android.app.TaskStackBuilder
To provide proper navigation.
1) When the app is launched by App icon (Normal Flow)
**
2) When the app is launched by some Notification
General flow of navigation in your app is MainActivity->DetailActivity
But sometimes a Notification might directly open the DetailActivity. In this case, pressing the back button in DetailActivity will not lead you to the `MainActivity. It's an EXPECTED BEHAVIOR. However, you can modify this if you want to navigate back to MainActivity.
How do I do it?
1) Add android:parentActivityName="com.example.myApp.MainActivity in your Activity
This feature was added in Android 4.1. So if you want to target older devices. Add a meta-tag ALSO.
<activity android:name=".Activities.DetailActivity"
android:parentActivityName=".Activities.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".Activities.MainActivity" />
</activity>
2) Use TaskStackBuilder to create a Pending Intent.
public PendingIntent getPendingIntent(Intent intent){
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);
taskStackBuilder.addNextIntentWithParentStack(intent);
PendingIntent pendingIntent = taskStackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
}
Now pass this Pending intent to create Notifications.
We use a TaskStackBuilder to make sure that the back button will play nicely when the activity gets started. The TaskStackBuilder allows you to access the history of activities used by the back button. Basically, we use it when we want the user to navigate to another activity after pressing back button.
I know it has been a while but I came across this problem, this time, my stack had several levels of depth. Looking at the good answers here, I was able to infer it for 3 levels or more of course. As it looks straight forward, it did not look so at the beginning for me because I was triplicating the back stack. Hope it helps someone. Be sure to have the Manifest.xml set up properly
Anyway, for those with several levels, this works nicely:
Intent level3Intent = new Intent(this, Level3.class);
level3Intent.putExtra(YOUR STUFF);
Intent level2Intent = new Intent(this, Level2.class);
//level2Intent.putExtra(YOUR STUFF);
Intent level1Intent = new Intent(this, MainActivity.class);
// Get the PendingIntent containing the entire back stack with the needed extras
PendingIntent pendingIntent =
TaskStackBuilder.create(this)
.addParentStack(MainActivity.class)
.addNextIntent(level1Intent)
.addNextIntent(level2Intent)
.addNextIntent(level3Intent)
.getPendingIntent(requestCode, PendingIntent.FLAG_UPDATE_CURRENT);
return new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
.setContentTitle(notification_title)
.setContentText(notification_msg)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(notification_msg))
.setSmallIcon(R.drawable.ic_sea)
.setDefaults(Notification.DEFAULT_SOUND)
.setWhen(System.currentTimeMillis())
.setGroup(OWS_GROUP)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
The other answers explained it nicely: you use a pending intent to send a user into a detail activity, then you want them to use the back button to go back to the main activity. An alternative way to set this is
Intent detailIntentForToday = new Intent(context, DetailActivity.class);
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
taskStackBuilder.addNextIntentWithParentStack(detailIntentForToday);
PendingIntent resultPendingIntent = taskStackBuilder
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
resultPendingIntent.send();
For this, you also need to set
android:parentActivityName=".MainActivity"
for the DetailActivity in AndroidManifest.xml.
I had the same problem and I solved in this way:
As already suggested, I added
android:parentActivityName=".MainActivity" in my AndroidManifest file.
I also added to every classes the method onResume
I used TaskStackBuilder to create a Pending Intent:
Intent intent = new Intent(context, myClass);
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
taskStackBuilder.addNextIntentWithParentStack(intent);
PendingIntent pendingIntent = taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

Launching an activity of the application on clicking the notification

I like to launch one of my activities in my application on clicking the notification.
I designed a pending intent as discussed in the link Notifications.
But when i click the notification, an activity is launched but that is not the activity supposed to launch from my application. Just the activity that has same class name as my activity is launched. I set a break point in my activity and the break point is never hit.
What is wrong? NotificationListActivity is the one I like to launch. Now the activity titled with NotificationListActivity is launched, but not my activity.
Intent resultIntent = new Intent(thisclasscontext, NotificationListActivity.class);
resultIntent.putExtra("MOBILENUMBER", tel);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(thisclasscontext);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(NotificationListActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
You can use the below as a reference it works
public void notification()
{
int mId=1;
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("My notification")
.setContentText("Hello World!");
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(MainActivity.this, SecondActivity.class);
// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(MainActivity.this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(SecondActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());
}

Categories

Resources