I'm trying to create a notification when an alarm fires. No problem so far.
A notification is shown. The problem is on my device (2.1 Update 1) it is displayed as an ongoing notification. While on another device (2.2) it is working fine and is actually shown as a one time only notification. Has anyone experienced this behaviour, and more important has anyone been able to fix it. It seems like 2.1 is not respecting the FLAG_ONLY_ALERT_ONCE or any flags for that mather. See my code below. Any help would be appreciated.
public class AlarmHandler extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
Debug.log("Alarm notification received");
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence from = intent.getStringExtra("AlarmType");
CharSequence message = intent.getStringExtra("AlarmType");
Intent newIntent = new Intent(context, Splashscreen.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, intent.getIntExtra("RequestCode", 0),
newIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
Notification notif = new Notification(R.drawable.icon,
null, System.currentTimeMillis());
notif.setLatestEventInfo(context, from, message, contentIntent);
notif.flags |= Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_AUTO_CANCEL;
Debug.log("flags: "+notif.flags);
Debug.log("Defaults: "+notif.flags);
nm.notify(intent.getIntExtra("RequestCode", 0), notif);
}
}
Please find below values and definition for each one. Hope you can get idea from this.
FLAG_ONLY_ALERT_ONCE = 8
Definition : It 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.
FLAG_ONGOING_EVENT = 2
Definition: It should be set if this notification is in reference to something that is ongoing, like a phone call. It should not be set if this notification is in reference to something that happened at a particular point in time, like a missed phone call.
FLAG_AUTO_CANCEL = 16
Definition: The notification should be canceled when it is clicked by the user
Also you if you want to cancel the notification manually then use below code
nm.cancel(id);
Related
I have implemented smooch. https://smooch.io/
And my issue is that when I get the notification from smooch. If I'm in the background, I set a "unread messages" long that I use in my main activity on the smooch button.
The issue is that when I press on the notification, and the ConversationActivity is started from there. I need to set the unread messages to 0, because the ConversationActivity is opened. How can I know when this happens?
I cannot modify ConversationActivity.class from the smooch library.
I thought about making the notification myself, and changing the smooch created one with this one using this code:
private static void generateNotificationSmooch(final Context context, String title, String message) {
if (title == null)
title = context.getString(R.string.passenger_name);
Intent notificationIntent = new Intent(context, ConversationActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
int iUniqueId = (int) (System.currentTimeMillis() & 0xfffffff);
PendingIntent intent = PendingIntent.getActivity(context, iUniqueId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle(title).setContentText(message).setSmallIcon(R.drawable.notification_icon);
mBuilder.setContentIntent(intent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}
But I need to set the unread to 0 when the notification is pressed, and not when I create the notification. And I can't put it in pending intent
You have a few options.
Use the onSmoochShown delegate callback.
This callback will be triggered when the conversation is shown, so you will be able to update your unread count.
Use the onUnreadCountChanged delegate callback
.
This delegate will be called whenever the unread count changes for current user. You can use this callback to update your long accordingly.
Since you will need to be listening to these delegate callbacks when a notification is tapped, it may be best to set your delegate in your Application’s onCreate, after you initialize Smooch.
I guess it is hard to explain just by reading the title of this question. I am coding an app that gets ambient factors alerts (temperature, etc) sent by a known server to GCM, and then GCM sends it back to the phone. The whole GCM works well. The problem is when notifications arrive. It is thought to send notifications to the phone when an alert happens (a trigger). Then clicking on the alert launches the activity to display the alert. That is OK, but if there is 2 or more alerts on waiting to be clicked, it will only process one, ignoring the rest ("mensaje"). This is how my notification inside a class that extends extends GcmListenerService looks like.
public static void showAlerts(Context context, String mensaje)
{
Intent notificationIntent = new Intent(context.getApplicationContext(), MainActivity.class);
notificationIntent.putExtra("mensaje", mensaje);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
Random r = new Random();
PendingIntent pendingIntent = PendingIntent.getActivity(context, r.nextInt(),
notificationIntent, 0);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(context)
.setContentTitle(context.getString(R.string.app_name))
.setContentText("Nueva alerta recibida")
.setSmallIcon(R.drawable.termometrorojo)
.setNumber(UtilidadesGCM.num_notificaciones++)
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
.setDefaults(Notification.DEFAULT_LIGHTS)
.setAutoCancel(true).build();
notificationManager.notify(0, notification);
}
Then in MainActivity, I have the code to process this, and open the activity to display the alert
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
String nuevaAlerta = intent.getExtras().getString("mensaje");
procesaAlerta(nuevaAlerta);
//mDisplay.append(nuevaAlerta + "\n");
}
};
public void procesaAlerta (String alerta)
{
Intent intent = new Intent(this, Alertas.class);
intent.putExtra("mensaje" , alerta);
startActivity(intent);
}
The Alertas class will parse the message fine and display it in its activity, but will only do that once. If there are more than 2 alerts stacked to be read, it only process one. If there is one, it works ok. Sorry if I odn't explain better, but it hard not showing all the code.
Thanks!
Try with writing this line
notificationManager.notify( new Random().nextInt(), notification);
instead of
notificationManager.notify(0, notification);
Your notification id is every time same so your last notification only work. Every new notification id is replaced by id 0. So i use random id instead of fixed id 0. I think above code will work for you
Is it possible not launch new activity if we receive a push notification while the app is running?
My activity works with fragments and I want to do transition to a determinate fragment when the notification is received. My activity have data that I need to show the fragments. The problem is that when I receive the push notification while the app is running the method onDestroy is called and here I clear the data and then the app crash because the data are null. How can I do to not create new activity when the app receive a push notification while is running? In case the app is running I want that if you click the notification do a transition fragment, not create again the activity.
Thanks in advance.
First of all, I think that you mean "notification" to be a "message", but not android.app.Notification class.
And second, I don't think it's a best practise to raise new GUI when receiving a message, which would interrupt the user interaction. For details, please refer to: http://developer.android.com/training/notify-user/index.html and http://developer.android.com/design/patterns/notifications.html.
At last, if you really wanna do what you stated in your thread, I wonder why the data used to generate the show-data fragment is held in the activity. Try holding the data in an android.app.IntentService object, and then generate transfer the data to new activity, and then use android.app.Fragment.setArguments method to transfer the data from activity to fragment.
I think that this code will help you. This which you need is PendingIntent, it make transaction to desired activity.
/**
* Issues a notification to inform the user that server has sent a message.
*/
private static void generateNotification(Context context, String title,
String message) {
//get the default notification sound URI
Uri uriNotificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
//make intent to the application. if the application is opened just maximize it.
Intent homeIntent = new Intent(context, 'your desired activity');
homeIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
homeIntent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("eCommCongress")
.setContentText(message)
.setLights(Color.GREEN, 1500, 1500)
.setSound(uriNotificationSound)
.setAutoCancel(true)
.setContentIntent(contentIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(counter, mBuilder.build());
counter++;
}
It is perfectly possible and I do such a thing in one of my apps. First, you need to declare your activity as android:launchMode="singleTop",
Then, when you build you must configure your pending intent not to fire a new instance of your activity:
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent("YOUR ACTION HERE");
intent.setClassName(this, MainActivity.class.getName());
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentIntent(resultPendingIntent);
Notification notification = mBuilder.build();
notification.defaults |= Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS;
notification.flags |= Notification.FLAG_SHOW_LIGHTS | Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(idNotificacion,notification);
Now all you have to do is to override your onNewIntent inside your Activity and do whatever you want with your fragment:
#Override
protected void onNewIntent(Intent intent) {
MiLog.i(getApplicationContext(),"IntentShit","new intent received");
MiLog.i(getApplicationContext(),"IntentShit","Action: "+intent.getAction());
if(intent.getAction()!=null && intent.getAction().equals("YOUR ACTION HERE"){
//DO your stuff here
}
}
You should also take a look at this page for more info:
http://www.intridea.com/blog/2011/6/16/android-understanding-activity-launchmode
I have a GCMIntentService class, in which i get some messages returned from my server. I want to be able to start a certain activity when a certain message arrives at my app. For example if in my onMessage() method (onMethod() is the method, and the first place, in the app, that receives the messages from the server) arrives the string = "tomatoe", i want to start a specific activity. The way i know right now to start an activity, is this:
Intent resactivity = new Intent(getApplicationContext(), ResponseActivity.class);
resactivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(resactivity);
The problem is that GCMIntentService, is not a class that extends activity, and i believe that i can't use this code for this purpose. Is there some way to initiate an activity from a class that is not an activity, by creating an intent inside that class?
The problem is that GCMIntentService, is not a class that extends activity, and i believe that i can't use this code for this purpose.
GCMIntentService inherits from Context, which is where startActivity() is defined.
Bear in mind, though, that your users may attack you with pitchforks or machine guns for popping up activities at random points in time, perhaps in the middle of something else that they are doing. Please make this behavior configurable, or else make very very certain that your users will appreciate these interruptions.
I post the method I usually use to start an activity when a notification arrives in my apps. Take a look to all the configurations and remove those you are not interested in:
#Override
protected void onMessage(Context context, Intent intent) {
String app_name = context.getString(R.string.app_name);
String message = intent.getStringExtra("payload");
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(ns);
int icono = R.drawable.ic_stat_notify;
long time = System.currentTimeMillis();
Notification notification = new Notification(icono, app_name, time);
notification.defaults |= Notification.DEFAULT_SOUND;
Intent notificationIntent = new Intent(context, ResponseActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, -1, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.when = System.currentTimeMillis();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context, app_name, message, pendingIntent);
notificationManager.notify(0, notification);
}
You should be able to do it as such:
getApplication().startActivity(resactivity);
I've been fighting this for over a week now, so any help would be appreciated.
I have an Activity starting a Service for media playback. Once playback has begun, the Service starts an Ongoing, Non-Cancellable Notification as such:
realIntent = new Intent(this, EpisodeViewer.class);
realIntent.putExtra("show_name", showName);
realIntent.putExtra("episode_name", episodeName);
pendingIntent = PendingIntent.getActivity(this, 0, realIntent, 0);
note =
new Notification(
R.drawable.ic_notification_bcn,
episodeName,
System.currentTimeMillis());
note.flags =
note.flags |
Notification.FLAG_FOREGROUND_SERVICE |
Notification.FLAG_NO_CLEAR |
Notification.FLAG_ONGOING_EVENT;
note.setLatestEventInfo(this, "", episodeName, pendingIntent);
note.contentView =
new RemoteViews(
getApplicationContext().getPackageName(),
R.layout.episode_player_note);
note.contentView.setImageViewResource(
R.id.player_note_icon,
R.drawable.ic_notification_bcn);
note.contentView.setTextViewText(
R.id.player_note_text,
episodeName);
note.contentView.setProgressBar(
R.id.player_note_progress, 100, 0, false);
noteManager.notify(MEDIA_PLAYER_NOTIFY_ID, note);
And this works just fine. When the user switches to play something else (through the Activity's UI) the Service updates the Notification (using the same as above) to change the name and re-set the progress bar. And this works just fine. And as the media progresses, the progress bar in the Notification updates, and this works as well.
But when the media ends or the User wants to stop, the Service tries to cancel the Notification with
noteManager.cancel(MEDIA_PLAYER_NOTIFY_ID);
But this is ignored. There are no errors in the DDMS log, but from my trace I know for sure the cancel is being called. I've tried cancelling the PendingIntent before cancelling the Notification, but this makes no difference. I've also tried replacing the Notification with an 'Empty' one - clearing the progress and the name - and then cancelling. The new 'Cleared' Notification shows, but then still does not cancel.
So what am I missing here? Is there something else that needs to be done to cancel a FOREGROUND or NO_CLEAR or ONGOING Notification that I'm missing? I've tried this with the Emulator under 2.1 and 2.2, and on my hardware running 2.3, all of which exhibit the exact same behaviour.
I noticed the same problem.
If the notification flag has "Notification.FLAG_FOREGROUND_SERVICE" in it, the only way to get rid of it is to call "stopForeground()", but there is a catch. The "stopForeground()" won't remove the notification (with FLAG_FOREGROUND_SERVICE) if "startForeground()" has not been called!
In simple words, if you use FLAG_FOREGROUND_SERVICE, you have to call "startForeground()" and "stopForeground()"!
If "startForeground()" is used, I don't see a reason for putting FLAG_FOREGROUND_SERVICE in the other notifications. But if it is needed, here is a sample (used in public class CLASS extends Service) :
public int onStartCommand(Intent intent, int flags, int startId) {
PendingIntent notifIntent;
Intent notificationIntent = new Intent(); // fill up yourself
notifIntent = PendingIntent.getActivity(); // fill up yourself
Notification note = new Notification(); // fill up yourself
note.setLatestEventInfo(context, getString(R.string.app_name), Message, notifIntent);
startForeground(yourOwnNumber, note); // fill up yourself
displayYourNotification();
// Fill up the rest yourself.
}
public void onDestroy() {
stopForeground(); // fill up yourself
}
public void displayYourNotification() {
Intent notificationIntent = new Intent(); // fill up yourself
notifIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Notification note = new Notification(); // fill up yourself
note.flags = Notification.FLAG_FOREGROUND_SERVICE;
note.setLatestEventInfo(context, TITLE, Message, notifIntent);
notifManager.notify(ID, note);
}