Please have a look at my Pending Intent code.
notificationIntent.putExtra("is_from_notification", true);
notificationIntent.putExtra("push_message_id", push_message_id);
notificationIntent.putExtra("open_target", open_target);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(context,notifyID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification noti = new NotificationCompat.Builder(context)
.setSmallIcon(icon_small)
.setTicker(message)
.setLargeIcon(largeIcon)
.setWhen(System.currentTimeMillis())
.setContentTitle(title)
.setContentText(message)
.setContentIntent(contentIntent)
.setAutoCancel(true).build();
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notifyID, noti);
My Problem is that, where and how should I clear this pending intent. It stays as far as app is in recent tasks.
Just call notificationManager.cancel(notifyId);
Or
call notificationManager.cancelAll();
Hope , it helps.
To clear a pendingIntent use:
Edit:
PendingIntent.getActivity(context,notifyID, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT).cancel();
Place this line somewhere in your code, where u want to cancel the pendingintent.
Note: The intent must have the same name and ID as your pendingIntent, in your case: notifyID and contentIntent
Note: A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.
cancel() - Cancel a currently active PendingIntent. Only the original application owning a PendingIntent can cancel it.
Should help u out
Related
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setContentIntent(pendingIntent);
Does it mean that I can't jump to the mainActivity multiple times by repeatedly clicking this notification? Is pendingIntent.send() called internally when I clicks the notification? Does this flag become meaningless in the notifications?
PendingIntent.FLAG_ONE_SHOT means that the PendingIntent will be deleted after it is used once. Normally, a PendingIntent can hang around if there are other references to it in the system.
This flag can be used to prevent multiple uses of the PendingIntent, although my personal experience is that this flag generally causes more problems than it solves.
You asked:
Is pendingIntent.send() called internally when I clicks the notification?
Yes, that's basically what happens when you click on the UI element associated with the PendingIntent in the Notification.
When app receives message from GCM, it shows notification.
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_event_white_24dp)
.setContentTitle("TheBriefPost")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
When I click on notification, app opens activity but not restarting. What is the problem? How to solve it?
The answer should be related to the flags of the Intent/Pending Intent
According to PendingIntent in Official Docs
In the Pending Intent you sent a flag PendingIntent.FLAG_UPDATE_CURRENT
Flag indicating that if the described PendingIntent already exists, then keep it but replace its extra data with what is in this
new Intent.
I guess in your case you need to use PendingIntent.FLAG_CANCEL_CURRENT
Flag indicating that if the described PendingIntent already exists, the current one should be canceled before generating a new one.
Accodring to Activity in Official Docs
In the Activity you set the flag Intent.FLAG_ACTIVITY_SINGLE_TOP
If set, the activity will not be launched if it is already running at the top of the history stack.
I guess here you need to use Intent.FLAG_ACTIVITY_CLEAR_TASK
If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started.
app opens activity but not restarting
It should not be restarted. FLAG_ACTIVITY_SINGLE_TOP is "If set, the activity will not be launched if it is already running at the top of the history stack."
Why you want it restarted? To handle intent data? If so, implement onNewIntent() in your activity.
My Android application receives push notification with some text messages.If I tap a push it redirects me to desired activity with latest push message (intent message) but I want to show my desired activity with corresponding push messages.
For example If I receives 10 push notifications and I tap 3rd notification, my code redirects me to the specified activity with 10th push notification's message, but I want to show 3rd intent push notification's message.
I know PendingIntent.FLAG_UPDATE_CURRENT replace the intent message, how can I redirect with corresponding message instead last message?
I have tried the following:
Intent intent = new Intent(this, TestActivity2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("uid", uid);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
getApplicationContext());
Notification notification = mBuilder
.setSmallIcon(R.drawable.ic_launcher)
.setTicker(textMsg)
.setWhen(0)
.setAutoCancel(true)
.setContentTitle(textMsg)
.setStyle(
new NotificationCompat.BigTextStyle().bigText(textMsg))
.setContentIntent(resultPendingIntent).setContentText(textMsg)
.build();
NotificationManager notificationManager = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify((int) System.currentTimeMillis(),
notification);
Use FLAG_ONE_SHOT instead and change the second parameter in getActivity which is set to 0. This answer will make it clear.
You should Change the pendingIntend's content for Different Messages.
Here is the snippet from PendingIntent document.
"A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it."
In simple words...try passing different id(Something like currentEpochTime) for each pendingIntent.
I have a service in background which gives a notification.
I want the next thing:
If I click the notification and the app is not opened open the XActivity.
If the app is opened and the XActivity is created, go there and don't recreate the activity (because if this happen, on back key i will see the same activity again).
My notification code
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("New posts!")
.setContentText("New funny posts had just arrived! Click here to see them!");
mBuilder.setAutoCancel(true);
Intent resultIntent = new Intent(context, XActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
int mNotificationId = 001;
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
I start the service from the XActivity. (just a activity name example)
Thank you.
i had the same problem, what i did was , i added this line android:launchMode="singleTop" to my activity in manifest, and it worked.
Problem for duplicate activity in your case is because of standard structure design of Activity in Android. For creating only single instance of activity (no duplication) you need to give launchMode property to your activity in your manifest file. You can use singleTop property for this behaviour. You can read more in provided link.
In Addition, for new data access you can use onNewIntent() for new intent coming to this activity and set intent using setIntent() and continue working with new data.
Hope this helps.
Thanks.
I am reading a tutorial on pending intent and how it is used with notification manager.
In that page, the following code is mentioned :
Intent intent = new Intent(this, NotificationReceiverActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification noti = new Notification.Builder(this)
.setContentTitle("New mail from " + "test#gmail.com")
.setContentText("Subject").setSmallIcon(R.drawable.icon)
.setContentIntent(pIntent)
.addAction(R.drawable.icon, "Call", pIntent)
.addAction(R.drawable.icon, "More", pIntent)
.addAction(R.drawable.icon, "And more", pIntent).build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// hide the notification after its selected
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);
I want to ask why the notification manager needs to be provided a pending intent (why does it need my app's identity to send an intent) ?
Why can't it be just given an intent ?
Edit : Please don't answer with the definition of pending intent. I know what a pending intent is. What I am interested in finding is why can't the notification just use a normal intent with some API like startActivity().
An Intent requires a context. If your application is not running then there is no context. Using a PendingIntent allows the system to invoke an intent with your application's permissions (context).
From http://www.simplecodestuffs.com/what-is-pending-intent-in-android/:
The reason it’s needed is
because an Intent must be created and launched from a valid Context in
your application, but there are certain cases where one is not
available at the time you want to run the action because you are
technically outside the application’s context (the two common examples
are launching an Activity from a Notification or a BroadcastReceiver.
Also see this StackOverflow answer.