Android API7 clearing ongoing notification - android

from my service I send (with "ongoing" ID = 0) ongoing notification and it seems that there is no way of clearing it from code. if I send other notifications to the same ID (0), icon and intents
will update :/
I dont know if this is a bug in API 7 but it just dont make sens to me.
when I sent notification with Notification.FLAG_ONLY_ALERT_ONCE with different ID(ex. 1) then it is classified as simple notification and I could easily clear it from expanded menu or from code. BUT just by sending same notification to previous ID (0) it is classified as ongoing and I cannot cancel it anyhow!
I also tried to save reference to "ongoing" notification and then re-notify it with other PendingIntent and/or flags but it has no effect!
my current code of the service
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d(TAG, "start notification");
startStatusBarNotification();
//do other stuff
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}
private void startStatusBarNotification()
{
Log.d(TAG, "startStatusBarNotification.");
final int icon = R.drawable.stbar_icon_fail;
final long when = System.currentTimeMillis();
final Notification notification = new Notification(icon, getString(R.string.notify_title), when);
final Intent notificationIntent = new Intent(this, MyActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(this, getString(R.string.notify_title), expandText, contentIntent);
notification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE;//| Notification.FLAG_NO_CLEAR
Log.d(TAG, "notify send.");
final NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(SERVICE_ONGOING_NOTIFICATION_ID, notification);//ID = 0
}
#Override
public void onDestroy()
{
Log.d(TAG, "clear status bar notification.");
cancelNotification();
super.onDestroy();
}
private void cancelNotification()
{
final int icon = R.drawable.stbar_icon_exit;
final long when = System.currentTimeMillis();
final Notification notification = new Notification(icon, getString(R.string.notify_title), when);
final PendingIntent contentIntent = PendingIntent.getActivity(this, 0, null, PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(this, getString(R.string.notify_stopping_title), getString(R.string.notify_stopping_text), contentIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
final NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(SERVICE_ONGOING_NOTIFICATION_ID); //NOTHING HAPPENS
mNotificationManager.notify(SERVICE_ONGOING_NOTIFICATION_ID, notification); //ID = 0 but if this was changed to 1 cancel notification can be cleared :/
}
I can see "exit" icon so onDestroy and cancelNotification are called, i have no idea what im doing wrong

It does not appear that you can successfully cancel ongoing notifications with ID 0: you will probably have to use a non-zero notification id.
The core notification manager service code is here, which doesn't appear to have a specific restriction on the choice of notification ID but everyone else who uses ONGOING notifications (for example, the Phone application) uses non-zero IDs.

Related

Prevent notification from being swiped off tray

Is it possible to prevent a notification from being swiped out of the notification tray? Like the usb notifications. If not, is there some sort of listener one can implement for that scenario?
You can do this by making your notifications sticky like this
private void makeNotification(Context context) {
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context,
NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(context)
.setContentTitle("Notification Title")
.setContentText("Sample Notification Content")
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_action_picture)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
;
Notification n;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
n = builder.build();
} else {
n = builder.getNotification();
}
n.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
notificationManager.notify(NOTIFICATION_ID, n);
}
You should set FLAG_ONGOING_EVENT.When you set this flag user can't dismiss your notification. For more info refer here
Constant Value: 32 (0x00000020)
public static final int FLAG_ONGOING_EVENT
Added in API level 1
Bit to be bitwise-ored into the flags field that 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.
Constant Value: 2 (0x00000002)
Of course, this is possible
My notification class:
public class ONots {
public static Notification notification(Context ctx, String title, int icon,
long when, PendingIntent pIntent, String contentTitle,
String contentText,int flags, int defaults){
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx);
Notification notification = builder.setContentIntent(pIntent)
.setSmallIcon(icon).setTicker(title).setWhen(when).setContentTitle(contentTitle)
.setContentText(contentText).setDefaults(defaults).build();
notification.flags = flags;
return notification;
}
}
somewhere in the code:
int defaults = Notification.DEFAULT_ALL;
int flags = Notification.FLAG_NO_CLEAR;
Notification notif = ONots.notification(this, shown_top, ico, System.currentTimeMillis(), pIntent, contentTitle, contentText, flags, defaults);
nm.cancel(_.NAKSNOT);
nm.notify(_.NAKSNOT, notif);

Persistent Notification Without Service

I am currently developing an app which is using AlarmManager to start an intent to show to the user every x minutes. I would also like a persistent notification in the status bar that shows the time until the next popup. Is there a way to show a persistent notification without a background service. If not does it make sense to stop using the AlarmManager and just use the service to popup the intent every x minutes?
Essentially I need to ensure that an intent will be launched every x minutes even if the phone gets low on mem and that the notification remains in the status bar. I would also like to be able to click on the notification to reset the timer that is counting down. What is the best way to achieve these objectives?
Thanks,
Nathan
To generate Notification try this :
private void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
String appname = context.getResources().getString(R.string.app_name);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
Notification notification;
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, myactivity.class), 0);
// To support 2.3 os, we use "Notification" class and 3.0+ os will use
// "NotificationCompat.Builder" class.
if (currentapiVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
notification = new Notification(icon, message, 0);
notification.setLatestEventInfo(context, appname, message,
contentIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context);
notification = builder.setContentIntent(contentIntent)
.setSmallIcon(icon).setTicker(appname).setWhen(0)
.setAutoCancel(true).setContentTitle(appname)
.setContentText(message).build();
notificationManager.notify(0 , notification);
}
}
Hope this helps.

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);
}

Trigger BroadcastReceiver using Push Notification in 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.

How to properly clear all notification once clicked?

I send a few notification on the notification bar, i wanted to clear all of it when one of the notification is clicked. For now I clear one by one by using Flag. I know notificationManager.cancelAll() could clear all the notification but where should i put so that i can trigger once one of the notification is clicked.
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);
// 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;
notificationManager.notify(msgid, notification);
//notificationManager.cancelAll(); //i wan to clear all when the notification is clicked, where should i put this line?
}
My solution is to call it at onResume().
#Override
protected void onResume() {
super.onResume();
// Clear all notification
NotificationManager nMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nMgr.cancelAll();
}
You should use a pending intent that sends a broadcast and then put in place a broadcast receiver that will cancel all your notifications. It is best to memorize all notifications IDs and delete them one by one.

Categories

Resources