I don't have any experience with notifications and after a long time now, I'm feeling really stupid, that I can't make it:
I'm getting push notifications from my server. On click of one, I'm getting the inormations with
getIntent().getBundleExtra("extra");
in the onResume method.
But if I'm getting a lot of notifications and don't open my application between this, then I'm just getting the last, if I click on the notification. Where are the notifications before? The best would be, if I'm getting a list of bundles or something like this. How can I do that?
Thanks for help, I'm really depressed :)
EDIT:
For better understanding: After receive a GCM I'm make a notification like this:
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, title, System.currentTimeMillis());
notification.sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
if (extras != null && launchIntent != null) {
launchIntent.putExtra("extra", extras);
}
PendingIntent intent = PendingIntent.getActivity(context, -1, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(context, title, msg, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(0, notification);
Example: I get a GCM and set a notification. If I don't open my application, but get the next GCM, then my first notification will replaced by the new one. This could be many times. After a few notifications i click on it. If the app starts I will get all the notifications, which has been sent. At the moment I just get the last one. How can I get all?
mNotificationManager.notify(0/* 0 is your notification id */, notification);
creates a notification with id 0. Now when you receive another notification and you notify it with the same notificaionId (i.e 0). Hence the latter pending Intent replaces the previous pendingIntent.
Check the explanation for notify() in the docs =>
http://developer.android.com/reference/android/app/NotificationManager.html
The best option would be to save your data locally in some DB, preferences or the traditional way
File and whenever you receive a push notification from GCM save it locally and then notify.
Related
I'm experiencing this problem: If I click on the notification and my app is closed, HomeActivity is opened instead of the requested one.
I'm raising the notification like this:
Intent intent = new Intent(context, ArticleActivity_.class);
intent.putExtra(ArticleActivity.KEY_ARTICLE_ID, articleId);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 , intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(notification.getTitle())
.setContentText(notification.getBody())
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
Notification n = notificationBuilder.build();
n.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 , n);
And everything works fine if the application is opened. But if I close it, after clicking on the notification, HomeActivity will be opened instead of the one I configured.
You are having this problem because that is how FCM works. There are 2 types of push notifications. The first type is "notification" and the second type is "data". Both can be visualize as a JSON payload:
"notification": {
//key values
}
"data": {
//your custom key values
}
There is a third type which is a combination of both.
The "notification" type will create a default visual notification with default behavior when the app is not in the foreground. And it will execute whatever your write inside onMessageReceived when the app is open. The second type "data" will always do what you code inside onMessageReceived.
From the Firebase web console, you can send "notification" type or the combined type. For sending only "data" you need to send it from Firebase Functions or from a Server (that complies with the FCM requisites).
There is a trick you can do to get your goal. Combined payload, that can be send from the Firebase web console, contains "notification" and "data". The "data" key-values are available after the user click the notification. That information is available as extra data from the intent opening the default launcher Activity, so there you can change your Activity.
In your launcher Activity, add the following:
String notification = getIntent().getStringExtra("your-key");
if (notification != null) {
startActivity(new Intent(this, YourActivity.class));
}
This way you can validate that the Activity is being opened because the default notification was clicked, and is always a String because payload in push FCM must be by rule always String. In other cases, if the user simply opened the app, then the String will be null, and you don't redirect the user.
I am making an app for my university, now in which I want to send messages/information about events. How I can send info to them. I tried firebase but, it is working till push notification only. I want if someone clicks on the notification it should open a new activity with whole message/info any code reference will be very helpful.
use the payload to put information into your notification. this could be an event id. The text of your notification is is also set by your server.
Thanks to the payload, your app client knows what event ID was received with the notification (when notification was opened). Just ask your database about information from the received event id from the client and you have all you need.
public void getnotification() {
NotificationManager notificationmgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent intent = new Intent(this, your_acitivity.class);
PendingIntent pintent = PendingIntent.getActivities(this, (int) System.currentTimeMillis(), new Intent[]{intent}, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notif = new Notification.Builder(this)
.setSmallIcon(R.drawable.shadow_fiend)
.setContentTitle(notif_title)//Title of the notification
.setContentText(notif_detail)//Description of the notification
.setContentIntent(pintent)
.setAutoCancel(true)
.build();
notificationmgr.notify(0, notif);
}
When the above function is called a notification is generated and by clicking the notification the user is redirected to a specific activity. In the intent replace the your_acitivity.class to whatever activity you want to be redirected when notification is clicked.
Feel free to comment if I misunderstood your requirements.
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.
com push notification for Android app, All is working well but lets say if i send 5 push notification a day, i dont want user to see 5 notification icons at once on his phone. Its best if he sees only one.So is their any way where old notification is deleted and only latest is shown.
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
The method that displays the notification has an int parameter which represents the notification identifier. If you use a constant identifier, each new notification will replace the previous one.
you have to set the notification ID to be the same value. So then they get replaced as each one arrives.
int notificationId = 1 ;
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setAutoCancel(true);
builder.setSmallIcon(R.drawable.gcm_logo);
builder.setContentTitle("Test Title");
builder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationId, builder.build());
So you can maintain notification Id for different type of notifications. If you keep same notification ID for each notification then it would be updated in the same .
If you have any extras in the pending intent and you want to update those extras with the latest ones then generate pending intent with :
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(),
PendingIntent.FLAG_ONE_SHOT);
I have made an app that sets notifications in the drop-down status bar of Android phones. However, there is a bug in my code (sometimes the notifications are set, sometimes they are not). I want to be able TO CHECK (in the code) IF THE NOTIFICATION IS VISIBLE TO THE USER. (i.e. can the user see the notification in the status bar?).
How can I do this? (Thanks in advance).
Sample code is greatly appreciated.
I want to be able TO CHECK (in the code) IF THE NOTIFICATION IS VISIBLE TO THE USER. (i.e. can the user see
the notification in the status bar?).
How can I do this?
You can't, sorry. Update: Now possible with Android 4.3+ http://developer.android.com/reference/android/service/notification/NotificationListenerService.html#getActiveNotifications()
However, you can always simply cancel() it -- canceling a Notification that is not on-screen is perfectly fine. Conversely, you can always safely call notify() again for the same Notification, and it too will not cause a problem if the Notification is already on-screen.
EDIT:
NotificationManager.getActiveNotifications() was added in API 23 if you don't want to use the NotificationListenerService
Just to put all together. This is how it works
To build a notification,
Notification n = new Notification.Builder(MyService.this)
.setContentTitle("Notification Title")
.setContentText("Notification Message")
.setSmallIcon(R.drawable.myicon).build();
To make a notification sound call setSound() of Notification,
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification n = new Notification.Builder(MyService.this)
.setContentTitle("Notification Title")
.setContentText("Notification Message")
.setSound(alarmSound)
.setSmallIcon(R.drawable.myicon).build();
To cancel the notification after user selected and launched the receiver Intent, call setAutoCancel(),
Notification n = new Notification.Builder(MyService.this)
.setContentTitle("Notification Title")
.setContentText("Notification Message")
.setSound(alarmSound)
.setAutoCancel(true)
.setSmallIcon(R.drawable.myicon).build();
To make sound/vibrate only once for a particular notification use Notification.FLAG_ONLY_ALERT_ONCE. With this flag, your notification will make sound only once till it gets cancelled and you can call notify() as many times as you want with the notification id. Note that if you call cancel() or if user cancelled the notification or auto cancelled, notify() call will make the notification sound again.
n.flags |= Notification.FLAG_ONLY_ALERT_ONCE; // Dont vibrate or make notification sound
Finally to put the notification on notification panel,
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(notification_id, n);
Note that notification_id here is important if you want to use the notification effectively.( to keep single sound/vibration for a notification or to cancel a specific notification).
To cancel a particular notification,
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.cancel(notification_id);
You can cancel() a notification even if it doesn't exist or you can call notify() as many times as you want with the same id. Note that calling notify with different id will create new notifications.
So, regardless of whether the notification exist or not, if you call notify() again with the correct notification_id with the Notification.FLAG_ONLY_ALERT_ONCE flag set, you can keep your notification alive without disturbing the user with repeated sounds.
You need to set an id for each notification you make.
so you make a notification ..
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notId + selectedPosition, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, rightNow.getTimeInMillis() - offset, pendingIntent);
Notification notification = new Notification(R.drawable.icon, "TVGuide Υπενθύμιση", System.currentTimeMillis());
NotificationManager manger = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
notification.setLatestEventInfo(context, "Κανάλι: " + b.getString("channel"), "Εκπομπή: " + showname, pendingIntent);
manger.notify(notId, notification);
to clear it..
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,notId, intent, 0);
pendingIntent.cancel();
and to check if active..( existAlarm returns null if no pending intent available)
public PendingIntent existAlarm(int id) {
Intent intent = new Intent(this, alarmreceiver.class);
intent.setAction(Intent.ACTION_VIEW);
PendingIntent test = PendingIntent.getBroadcast(this, id + selectedPosition, intent, PendingIntent.FLAG_NO_CREATE);
return test;
}
So everything comes down to initialize an ID for each notification and how you make it unique.
A new method is introduced to the NotificationManager class in API 23:
public StatusBarNotification[] getActiveNotifications()
There exists a flag for that.
Notification notification = new Notification(icon, tickerText, when);
notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
FLAG_ONLY_ALERT_ONCE:
...should be set if you want the sound and/or vibration play each time the notification is sent, even if it has not been canceled before that.
Although, the notification will blink when it is sent again, but there won't be any sound or vibration.
It's possible now to check notifications outstanding in android 4.3 upwards
See here:
http://developer.android.com/reference/android/service/notification/NotificationListenerService.html#getActiveNotifications()
It seems that from Android M (API 23) it is possible to get your process like that, without using NotificationListenerService nor requiring additional permissions:
notificationManager.getActiveNotifications()
As of Android Marshmallow (API 23), you can recover a list of active notifications posted by your app. This NotificationManager method is getActiveNotifications(). More info here: https://developer.android.com/reference/android/app/NotificationManager.html#getActiveNotifications()