How to prevent Notification from clearing all activities in backstack - android

I am developing an android app with GCM push notification ,in which whenever the notification opens the page it clears all activities from backstack.
Intent intent = new Intent(this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(intent);
long[] vibrate = {0, 100, 200, 300};
Uri notification = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
PendingIntent contentIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
Bitmap largIcon = BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.mipmap.small_icon_notification)
.setContentTitle(getResources().getString(R.string.app_name))
.setLargeIcon(largIcon)
.setSound(notification)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg). setSound(notification)
.setStyle((new NotificationCompat.BigTextStyle()).bigText(msg)) .setAutoCancel(true);
mBuilder.setVibrate(vibrate);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify((int) System.currentTimeMillis(), mBuilder.build());

To prevent Notification from clearing all activities in backstack, you must setup a Special Activity PendingIntent. A special Activity doesn't need a back stack. Use the manifest to set up the activity task options and create the PendingIntent by calling getActivity().
A PendingIntent specifies an action to take in the future. It lets you pass a future Intent to another application and allow that application to execute that Intent as if it had the same permissions as your application, whether or not your application is still around when the Intent is eventually invoked
By giving a PendingIntent to another application, you are granting it the right to perform the operation you have specified as if the other application was yourself (with the same permissions and identity).
The following code snippet demonstrates the process:
// Instantiate a Builder object.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Creates an Intent for the Activity
Intent notifyIntent =
new Intent(new ComponentName(this, ResultActivity.class));
// Sets the Activity to start in a new, empty task
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Creates the PendingIntent
PendingIntent notifyIntent = PendingIntent.getActivity(this,0,notifyIntent,PendingIntent.FLAG_UPDATE_CURRENT);
// Puts the PendingIntent into the notification builder
builder.setContentIntent(notifyIntent);
// Notifications are issued by sending them to the
// NotificationManager system service.
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Builds an anonymous Notification object from the builder, and
// passes it to the NotificationManager
mNotificationManager.notify(id, builder.build());
Here's a useful link How to Setup a Special Activity PendingIntent:
http://developer.android.com/training/notify-user/navigation.html

From
PendingIntent contentIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
To
PendingIntent contentIntent = stackBuilder.getPendingIntent(99,
PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
Just change the requestCode and it works.

Related

The other notifications is lost the click behaviour, when a notification is chosen at device's system tray in android

If there're two my app's notifications at device's system tray, the user choose one notification, the app's opening but all of other notifications is lost the click behavior, it means user cannot click them anymore. How can I prevent this action?
My code:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.icon)
.setContentTitle(getString(R.string.test))
.setContentText(messageBody);
Intent intent = new Intent(this, NotifActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle bundle = new Bundle();
bundle.putString(NotificationViewActivity.MESSAGE_EXTRA, messageBody);
intent.putExtras(bundle);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
intent, PendingIntent.FLAG_ONE_SHOT);
builder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(new Random().nextInt(50) + 1, builder.build());
int mId = (int) System.currentTimeMillis();
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.imagename)
.setContentTitle("Title")
.setContentText("message")
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true);
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(context, activityname.class);
//activityname is the name of activity which you want to launch
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
// 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(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MainActivity.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) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());
I detected my root cause in below code
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Because the request code is the same for all notifications, so when we click to the one notification, the other lost their click listener. Fix like below codes
PendingIntent pendingIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent,
PendingIntent.FLAG_ONE_SHOT);

Android Push Notification Not opening the Activity if n number of notifications in Notification Bar

I am developing an android app and i am implemented GCM push notification also,and notification id is different for each,The problem is When i have n push notifications and app is not in background ,When i click on the notification first time it will open the activity. Then i again cleared the app instance from background and clicked on the another push notification it will not open the app.
Intent intent = new Intent(this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(intent);
long[] vibrate = {0, 100, 200, 300};
Uri notification = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
PendingIntent contentIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
Bitmap largIcon = BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.mipmap.small_icon_notification)
.setContentTitle(getResources().getString(R.string.app_name))
.setLargeIcon(largIcon)
.setSound(notification)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg). setSound(notification)
.setStyle((new NotificationCompat.BigTextStyle()).bigText(msg)) .setAutoCancel(true);
mBuilder.setVibrate(vibrate);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify((int) System.currentTimeMillis(), mBuilder.build());
In the line(s)
PendingIntent contentIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
you always use the same request code for the PendingIntent.
All instances of PendingIntent with the same request code (first argument) and same intent (maybe even that is unimportant, I did not test that yet) are the same pending intent, no matter what extras you put to the intent. The only way to make them different is to use different request codes.
Especially if you use the FLAG_ONE_SHOT, a "Flag indicating that this PendingIntent can be used only once"
I removed PendingIntent.FLAG_ONE_SHOT and pending intent request code to a random number. Now it works fine.

Android Notification intent destroyes activity

I'm trying to use notifications in my app, but I've got a problem using following code:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification)
.setContentTitle("title")
.setContentText("message");
builder.setOngoing(true);
Intent resultIntent = new Intent(this,StartActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(StartActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
builder.setContentIntent(resultPendingIntent);
notificationManager.notify(1, builder.build());
When I return to homescreen and click the notification in the status bar StartActivity gets destroyed and created again. But, I just want the Activity to show again like clicking the launcher icon would do in this ,moment. How can I change that?
regards
Try adding
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Before you create the PendingIntent
Source:
How to make notification intent resume rather than making a new intent?
Following worked for me:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification)
.setContentTitle("title")
.setContentText("message");
builder.setOngoing(true);
Intent resultIntent = new Intent(this,NotificationActivity.class);///!!!!
resultIntent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
notificationManager.notify(1, builder.build());
NotificationActivity is special class, which finishs immediately in onCreate() and brings the task of the app to foreground. Source: Notification to restore a task rather than a specific activity?

android clear intent which send from notification

My app is getting called by an intent that is passing information(pendingintent in statusbar) but when I hit the home button and reopen my app by holding the home button it calls the intent again and the same extras are still there...
is there any way to clear the intent? or check whether it has been used before?
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("reportID", reportID);
intent.putExtra("message", message);
intent.putExtra("toast_show", true);
intent.putExtra("detail_open", true);
intent.putExtra("SplashActivity", true);
PendingIntent pendingIntent = PendingIntent
.getActivity(context.getApplicationContext(), 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
// Intent.FLAG_ACTIVITY_NEW_TASK
/* get the system service that manage notification NotificationManager */
NotificationManager notificationManager = (NotificationManager) context
.getApplicationContext().getSystemService(
Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
context.getApplicationContext())
.setWhen(when)
.setContentText(message)
.setContentTitle(title)
.setSmallIcon(smalIcon)
.setAutoCancel(true)
.setTicker(message)
.setLargeIcon(largeIcon)
.setDefaults(
Notification.DEFAULT_LIGHTS
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_SOUND)
.setContentIntent(pendingIntent);
/* Create notification with builder */
Notification notification = notificationBuilder.build();
notificationManager.notify(0, notification);
The problem starts when I receive a notification. If I start the app from the notification, it starts the correct screen and I can use the app => ok. But when I quit the app (with home or back button) it do not appears anymore in the "recent app" list. More precisely:
Does anyone knows how to keep the app in the "recent app" list after being started form a notification?
Update this line and try
PendingIntent pendingIntent = PendingIntent.getActivity(context, (int)(Math.random() * 100),intent,PendingIntent.FLAG_UPDATE_CURRENT);
What you need is the PendingIntent.FLAG_CANCEL_CURRENT :
If the described PendingIntent already exists, the current one is canceled before generating a new one. You can use this to retrieve a new PendingIntent when you are only changing the extra data in the Intent; by canceling the previous pending intent, this ensures that only entities given the new data will be able to launch it.
PendingIntent pendingIntent = PendingIntent.getActivity(
context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
This will ensure that your latest data will pe present on your Intent.

Android notification Resume Activity

I'm trying to make a notification when users pause my app. So to make it easier, users can go quickly to the application using notificaction. This is the code i'm using. It works for all versions before android 4 and i don't know which is the problem
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Titulo")
.setContentText("Titulo");
mBuilder.setOngoing(true);
// Creates an explicit intent for an Activity this
Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
// put the flags
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MainActivity.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());
So when i press the notification in android 4.0 and higher, the activity is created again instead of resume. any help please, i can't make it work.
EDIT ( forget about manifest singletop )
android:launchMode="singleTop" same result, not working...
My activity contains a map. I'm using the new version of google maps. v2.
I just tried PendingIntent.FLAG_CANCEL_CURRENT and seems to work for me
public void showNotification(String header,String message){
// define sound URI, the sound to be played when there's a notification
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent intent = new Intent(this, MainActivity.class);
//PendingIntent.FLAG_CANCEL_CURRENT will bring the app back up again
PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,PendingIntent.FLAG_CANCEL_CURRENT, intent, 0);
Notification mNotification = new Notification.Builder(this)
.setContentTitle(header)
.setContentText(message)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setSound(soundUri)
.addAction(R.drawable.ic_launcher, "View", pIntent)
.addAction(0, "Remind", pIntent)
.setOngoing(true)//optional
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, mNotification);
}
Use android:launchMode="singleTop" in the manifest declaration of MainActivity
The only solution that actually worked for me after doing a lot of search is to do the following :
NotificationCompat.Builder builder = new NotificationCompat.Builder(this).set...(...).set...(..);
Intent resultIntent = new Intent(this, MainClass.class);
resultIntent.setAction("android.intent.action.MAIN");
resultIntent.addCategory("android.intent.category.LAUNCHER");
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, builder.build());
this opens your current activiy without creating another one !
SOLUTION provided by #Patrick taken from the question and added as answer:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.logo)
.setContentTitle(getString(R.string.txt))
.setContentText(getString(R.string.txt));
mBuilder.setOngoing(true);
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, Activity.class);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
// 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.from(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(Activity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, 0);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.getNotification());

Categories

Resources