Trigger BroadcastReceiver using Push Notification in Android - android

How do I trigger broadcast as soon as I click on notification!?

On the class extending GCMBaseIntentService in onMessage() call setNotificationMethod as below
private void setNotification(int defaults, String message, int flag) {
NotificationManager mNotificationManager;
int MOOD_NOTIFICATIONS = 12345;
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// This method sets the defaults on the notification before posting it.
Intent handleNotification = new Intent(this, PushNotifier.class);
handleNotification.putExtra("Result", resultfrmServer);
// This is who should be launched if the user selects our notification.
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
handleNotification, PendingIntent.FLAG_UPDATE_CURRENT);
final Notification notification = new Notification(
R.drawable.ic_launcher, // the icon for the status bar
message, // the text to display in the ticker
System.currentTimeMillis()); // the timestamp for the
// notification
notification.setLatestEventInfo(this, // the context to use
getText(R.string.app_name),
// the title for the notification
message, // the details to display in the notification
contentIntent); // the contentIntent (see above)
notification.defaults = defaults;
notification.flags = flag;
mNotificationManager.notify(MOOD_NOTIFICATIONS,notification);
}
Now when the notification is clicked PushNotifier class is started. Here you can decide whether you want to launch some other activity or register broadcast receiver. Also if you need information received in pushnotification you can send it to pushNotifier class using pending intent and user accordingly.

Related

Incorrect timestamp on future notifications

When my application is launched, it performs an API call and then schedules notifications based on the results. This amounts to around ~10 notifications being scheduled. There seems to be an issue with the timestamp displayed on the actual notification being incorrect.
Since I am creating these notifications and then scheduling an alarm with an AlarmManager, the default time present on the notification will be the time at which the notification is created (System.currentTimeMillis()).
I've tried to use the .setWhen() method on my Notification.Builder to set it to the time I am using to schedule the previously mentioned alarm. This is a little better, however, because notifications are not guaranteed to be delivered at the exact time specified, I often get notifications a few minutes in the past.
Additionally, I tried to manually override the when field on the notification in my BroadcastReceiver, right before .notify() is actually called:
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
notification.when = System.currentTimeMillis();
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
}
}
However, in the above scenario, it seems that .when is ignored.
Frankly, I am simply looking for a way to have the timestamp displayed on the notification be the time at which it is actually displayed.
I would suggest passing in your notification's information as extras then building the notification inside of the BroadcastReceiver. This will build the notification just before it is issued, so it will have the same time your AlarmManager triggers the BroadcastReceiver.
From wherever you're scheduling the notification:
private void scheduleNotification(){
// Create an intent to the broadcast receiver you will send the notification from
Intent notificationIntent = new Intent(this, SendNotification.class);
// Pass your extra information in
notificationIntent.putExtra("notification_extra", "any extra information to pass in");
int requestCode = 1;
// Create a pending intent to handle the broadcast intent
PendingIntent alarmIntent = PendingIntent
.getBroadcast(this, requestCode, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// Set your notification's trigger time
Calendar alarmStart = Calendar.getInstance();
alarmStart.setTimeInMillis(System.currentTimeMillis());
alarmStart.set(Calendar.HOUR_OF_DAY, 6); // This example is set to approximately 6am
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// Set the alarm with the pending intent
// be sure to use set, setExact, setRepeating, & setInexactRepeating
// as well as RTC_WAKEUP, ELAPSED_REALTIME_WAKEUP, etc.
// where appropriate
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmStart.getTimeInMillis(), alarmIntent);
}
Then, inside your BroadcastReceiver's onReceive:
String notificationExtra = null;
// Retrieve your extra data
if(intent.hasExtra("notification_extra")){
notificationExtra = intent.getStringExtra("notification_extra");
}
//Build the notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setSmallIcon(notificationIcon)
.setContentTitle(notificationTitle)
.setContentText(notificationMessage)
.setAutoCancel(true); // Use AutoCancel true to dismiss the notification when selected
// Check if notificationExtra has a value
if(notificationExtra != null){
// Use the value to build onto the notification
}
//Define the notification's action
Intent resultIntent = new Intent(context, MainActivity.class); // This example opens MainActivity when clicked
int requestCode = 0;
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
requestCode,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
//Set notification's click behavior
mBuilder.setContentIntent(resultPendingIntent);
// Sets an ID for the notification
int mNotificationId = 1;
// 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 have also been struggling with this for a bit, but your question actually brought me to the best answer. I checked out setWhen() and it seems like now this just works fine (checked with API lvl 30 & 31). As this post is a few years old, maybe this issue was fixed in the meantime. So here's how I did it in Kotlin:
class NotificationPublisher : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notification = intent.getParcelableExtra<Notification>(NOTIFICATION)
notification?.`when` = System.currentTimeMillis() // overwriting the creation time to show the current trigger time when the notification is shown
val postId = intent.getIntExtra(NOTIFICATION_ID, 0)
notificationManager.notify(postId, notification)
}
Your NotificationPublisher's onReceive() method will be invoked only when scheduled alarm triggers as specified time. When you crate a notification from onReceive() method, it will definitely show the current time. No need to require to use .when or .setWhen() method.
Try this one:
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
// Notification
Notification notification = new Notification.Builder(context)
.setContentTitle("This is notification title")
.setContentText("This is notification text")
.setSmallIcon(R.mipmap.ic_launcher).build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Notification Manager
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager .notify(id, notification);
}
}
If you want to redirect to an activity when click on Notification, then you can use PendingIntent and set it to your Notification.
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
Intent intent = new Intent(context, YourTargetActivity.class);
intent.putExtra("KEY_ID", id); // Pass extra values if needed
PendingIntent pI = PendingIntent.getActivity(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Notification
Notification notification = new Notification.Builder(context)
.setContentTitle("This is notification title")
.setContentText("This is notification text")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pI).build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Notification Manager
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager .notify(id, notification);
}
}
Hope this will help~

Notification is not being dismissed (Android)

Notification setAutoCancel(true) doesn't work if clicking on Action
I have a notification with an action within it. When I tap on the notification it gets removed from the list. However, when I click on the Action it successfully completes the Action (namely makes a call), but when I return to the list of notifications, it remains there.
Relative code of the AlarmReceiver:
public class AlarmReceiver extends BroadcastReceiver {
Meeting meeting;
/**
* Handle received notifications about meetings that are going to start
*/
#Override
public void onReceive(Context context, Intent intent) {
// Get extras from the notification intent
Bundle extras = intent.getExtras();
this.meeting = extras.getParcelable("MeetingParcel");
// build notification pending intent to go to the details page when click on the body of the notification
Intent notificationIntent = new Intent(context, MeetingDetails.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
notificationIntent.putExtra("MeetingParcel", meeting); // send meeting that we received to the MeetingDetails class
notificationIntent.putExtra("notificationIntent", true); // flag to know where the details screen is opening from
PendingIntent pIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
// build intents for the call now button
Intent phoneCall = Call._callIntent(meeting);
if (phoneCall != null) {
PendingIntent phoneCallIntent = PendingIntent.getActivity(context, 0, phoneCall, PendingIntent.FLAG_CANCEL_CURRENT);
int flags = Notification.FLAG_AUTO_CANCEL;
// build notification object
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
Notification notification = builder.setContentTitle("Call In")
.setContentText(intent.getStringExtra("contextText"))
.setTicker("Call In Notification")
.setColor(ContextCompat.getColor(context, R.color.colorBluePrimary))
.setAutoCancel(true) // will remove notification from the status bar once is clicked
.setDefaults(Notification.DEFAULT_ALL) // Default vibration, default sound, default LED: requires VIBRATE permission
.setSmallIcon(R.drawable.icon_notifications)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(meeting.description))
.addAction(R.drawable.icon_device, "Call Now", phoneCallIntent)
.setCategory(Notification.CATEGORY_EVENT) // handle notification as a calendar event
.setPriority(Notification.PRIORITY_HIGH) // this will show the notification floating. Priority is high because it is a time sensitive notification
.setContentIntent(pIntent).build();
notification.flags = flags;
// tell the notification manager to notify the user with our custom notification
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}
}
}
use this flag:
Notification.FLAG_AUTO_CANCEL
inside this:
int flags = Notification.FLAG_AUTO_CANCEL;
Notification notification = builder.build();
notification.flags = flags;
Documentation
Ok turns out it's a known problem already, and it needs extra code to be done (keeping reference to notification through id). Have no clue why API does not provide this, as it seems very logical to do. But anyways,
see this answer in stackoverflow:
When you called notify on the notification manager you gave it an id - that is the unique id you can use to access it later (this is from the notification manager:
notify(int id, Notification notification)
To cancel, you would call:
cancel(int id)
with the same id. So, basically, you need to keep track of the id or possibly put the id into a Bundle you add to the Intent inside the PendingIntent?
I faced this problem today, and found that FLAG_AUTO_CANCEL and setAutoCanel(true), both work when click on notification,
but not work for action click
so simply, in the target service or activity of action, cancel the notification
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancelAll();
or if have more notification
manager.cancel(notificationId);
You have created two pending intent use in boths and change Flag too.
PendingIntent pIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), notificationIntent, 0);
PendingIntent phoneCallIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), phoneCall, PendingIntent.FLAG_UPDATE_CURRENT);
// CHANGE TO THIS LINE
PendingIntent pIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
PendingIntent phoneCallIntent = PendingIntent.getActivity(context, 0, phoneCall, PendingIntent.FLAG_CANCEL_CURRENT);

Android: Manage multiple push notification in device of an app

I am developing an application in which i implemented Push notification functionality.
My code of onMessage - GCMIntentService.java is:
#Override
protected void onMessage(Context context, Intent data) {
String message = data.getExtras().getString("message");
displayMessage(context, message);
generateNotification(context, message);
}
And code of generateNotification -
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, GCMMessageView.class);
notificationIntent.putExtra("message", message);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
This code is working fine. I am getting push message and notification.
=>But when i send more then one message the notification gets over write. And i am able to see only last notification in status bar.
The need of application is that - if i send more then one notification then all should be display in status bar.
So please guide me what should i do for that in my code.
Try to put different notification id (i.e. nid) in intent and notify instead of 0 for each new notification this will prevent over writing your notification
PendingIntent intent = PendingIntent.getActivity(context, nid,notificationIntent, 0);
and
notificationManager.notify(nid, notification);
Hope this will help you
Get random numbers:
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
Instead of:
notificationManager.notify(0, notification);
use:
notificationManager.notify(m, notification);
You need to update your Notification ID when you fire a Notification. in
notificationManager.notify(ID, notification);
How?
To set up a notification so it can be different, issue it with a notification ID by calling NotificationManager.notify(ID, notification). To change this notification once you've issued it, create a NotificationCompat.Builder object, build a Notification object from it, and issue the Notification with the Different ID you are not used previously.
If the previous notification is still visible, the system updates it from the contents of the Notification object. If the previous notification has been dismissed, a new notification is created instead.
For more information go to official docs
hello you need to pass unique notification id in notify method.
Below is the code for pass unique notification id:
//"CommonUtilities.getValudeFromOreference" is the method created by me to get value from savedPreferences.
String notificationId = CommonUtilities.getValueFromPreference(context, Global.NOTIFICATION_ID, "0");
int notificationIdinInt = Integer.parseInt(notificationId);
notificationManager.notify(notificationIdinInt, notification);
// will increment notification id for uniqueness
notificationIdinInt = notificationIdinInt + 1;
CommonUtilities.saveValueToPreference(context, Global.NOTIFICATION_ID, notificationIdinInt + "");
//Above "CommonUtilities.saveValueToPreference" is the method created by me to save new value in savePreferences.
Let me know if you need more detail information or any query. :)
notificationManager.notify(Different_id_everytime, notification);

How to open same activity after clicked difference notifications

i spend a lot of time to resolve my problem. i have written a messenger client in android. my application receive income message and raise a notification. in notification bar i display each income message in a notification item. when click to notification item it will open a conversation activity to list all messages from the beginning until now. everything dose perfect but when i click another item in notification bar, nothing happen! (it must reload data for another conversation). This is my code to raise a notification:
private void showNotification(String message, Class activity, Message messageObject) {
//Get the Notification Service
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence text = message;//getText(R.string.service_started);
Notification notification = new Notification(R.drawable.ic_launcher, text, System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Intent callbackIntent = new Intent(context, activity);
if(messageObject != null)
{
callbackIntent.putExtra("conversation", MessageManager.getProvider().getConversation(messageObject.getConversationId()));
}
//callbackIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
int myUniqueValue = new Random().nextInt();
PendingIntent contentIntent = PendingIntent.getActivity(context, myUniqueValue, callbackIntent, PendingIntent.FLAG_ONE_SHOT);
notification.setLatestEventInfo(context, messageObject.getFrom(), text, contentIntent);
notificationManager.notify(messageObject.getFrom(), myUniqueValue, notification);
}
This is code block to call showNotification function
showNotification(message.getBody(), ConversationActivity.class, messageObject);
Despite your efforts to supply a unique value, those PendingIntents are all treated as the same by the system, so once you click one, the rest are rendered inert.
You'll need to add something distinguishing to callbackIntent; I suggest inventing a data URI that includes the conversation ID or something else that's guaranteed to be different for each notification (see setData).
Finally, I'd encourage you to try to collapse multiple notifications into one icon—you don't want to spam the user. See the Notifications section in the Android Design guide, under "Stack your notifications".
i changed my code and it work very well
private void showNotification(Context context, CharSequence contentTitle, CharSequence contentText, CharSequence notificationContent, Class activity, Conversation conversation) {
//Get the Notification Service
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher, notificationContent, System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Intent callbackIntent = new Intent(context, activity);
if(conversation != null)
{
callbackIntent.putExtra("conversation", conversation);
}
callbackIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
int myUniqueValue = new Random().nextInt();
PendingIntent contentIntent = PendingIntent.getActivity(context, myUniqueValue, callbackIntent, PendingIntent.FLAG_ONE_SHOT);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notificationManager.notify(myUniqueValue, notification);
}

Android Show Notification only when Message arrives

In Android, I have implemented Google Cloud Notification, which notifies when any message arrives, but it stays even when message is there, it shows icon in notification bar immediatly after installing application, is there any way to only show the notification when message arrives and hide it once the user clicks on it ??
Here is my code :
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
//Intent notificationIntent = new Intent(context, MainActivity.class); //Open Activity
// set intent so it does not start a new activity
Intent notificationIntent = new Intent(Intent.ACTION_VIEW);
notificationIntent.setData(Uri.parse("http://www.google.com")); //Open Link
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
Without seeing where you are receiving messages and where you want to generate and cancel Notifications, it is very difficult to discern what you need to do to implement this, but I will give it a shot.
If you load the sample project for an Android Connected App Engine project (via GCM), you will notice that GCM data is received in a GCMBaseIntentService.
This class has a method you can override called onMessage() that will be called whenever you receive a GCM message. If you create the notification in this method, then your application will only generate a notification when a GCM message is received.
As for cancelling notifications- you can do so by calling the NotificationManager's cancel() method, passing the ID of the notification you want to cancel. Presumably you have some sort of Activity that displays messages to the user, and this would be a good place to cancel any outstanding Notifications relating to a specific message.

Categories

Resources