i'm building a notification that is launched with a toggle button:
toggleLigar.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(toggleLigar.isChecked()){
NotificationUtil.cancelaAll(TelaCriaDesp.this);
CharSequence tickerText = "Despertador ativado!";
CharSequence title = "Você não vai perder seu ponto!";
CharSequence message = "O despertador " + despertador.getNomeDesp() + " está ativo!";
Intent intent = new Intent(TelaCriaDesp.this, TelaCriaDesp.class);
NotificationUtil.criaNotification(TelaCriaDesp.this, tickerText, title, message,
despertador.getDesp_id(), intent);
} else {
NotificationUtil.cancelaNotification(TelaCriaDesp.this, despertador.getDesp_id());
}
}
});
now i want to assign the toggle button in ON or OFF according to the notification state, if it's active (being displayed) it's ON, inactive OFF... I have tried this:
public static boolean testaNotification(int id, Context context){
Intent intent = new Intent(context, TelaCriaDesp.class);
//intent.setAction(Intent.);
PendingIntent teste = PendingIntent.getActivity(context, id, intent,
PendingIntent.FLAG_NO_CREATE);
return teste != null;
}
but it's not working, it always returns NULL...
here's my notification creation:
public class NotificationUtil {
#SuppressWarnings("deprecation")
public static void criaNotification(Context context, CharSequence tickerText, CharSequence title,
CharSequence message, int id, Intent intent){
PendingIntent aoSelecionar = PendingIntent.getActivity(context, 0, intent, 0);
Notification notification = null;
int apiLevel = Build.VERSION.SDK_INT;
if(apiLevel >= 11){
Builder montaNotification = new Notification.Builder(context)
.setContentTitle(tickerText)
.setContentText(message)
.setSmallIcon(R.drawable.icon)
.setContentIntent(aoSelecionar);
//montaNotification.setAutoCancel(true);
montaNotification.setOngoing(true);
if(apiLevel >= 17){
notification = montaNotification.build();
} else {
notification = montaNotification.getNotification();
}
} else {
notification = new Notification(R.drawable.icon, tickerText, System.currentTimeMillis());
notification.setLatestEventInfo(context, title, message, aoSelecionar);
//notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
}
NotificationManager manager = (NotificationManager)
context.getSystemService(Activity.NOTIFICATION_SERVICE);
manager.notify(id, notification);
}
From API 23 and up you can use NotificationManager method getActiveNotifications(). This returns a list of active notifications launched by your app in a form of an array.
So to check if a particular notification is active, you can just iterate over the elements of this array and compare notification ids/tags.
Read more on this method here:
NotificationManager.getActiveNotifications()
You cannot. You must track it manually, if You need.
In fact Notification is meant only to notify a user about some event. If you need to check if the notification is present - then, in fact, You need to check if the event (which the notification is about) is still valid.
In the case You described, You may persist information in the local database when creating a notification.
Add a contentIntent to the notification to be able to mark the database item appropriately when a user dismisses notification by clicking it.
Then when You need to test if the notification exists, just look for a valid row in the local database.
If You only have one simple notification of given type, You can just persist a boolean flag in a preference file without need for local database to use.
Related
Now in android i put this code in one activity to show notification when a button pressed.
static int notificationCount = 0;
then
btnNotification.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent notificationIntent = new Intent(AlertsActivity.this,NotificationActivitty.class);
PendingIntent pIntent = PendingIntent.getActivity(AlertsActivity.this,notificationCount,notificationIntent,Intent.FLAG_ACTIVITY_NEW_TASK);
// Construct the notification
Notification.Builder nBuilder = new Notification.Builder(AlertsActivity.this);
nBuilder.setContentTitle("You Have a notification!");
nBuilder.setContentText("See Your Notification");
nBuilder.setSmallIcon(android.R.drawable.btn_star);
nBuilder.setContentIntent(pIntent);
nBuilder.addAction(android.R.drawable.stat_notify_call_mute, "go to", pIntent); // from icecream sandwatch - required api 16
// Build the notification
Notification noti = nBuilder.build(); // required api 16
//Send it to manager
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
manager.notify(notificationCount++,noti);
}
}
);
From Notification manager, Any notification that i clicked on it, it will redirect me to another activity (NotificationActivity)
Now i put this code to clear the notification but it only clear the notification with id 0 so how can i clear the current pressed notification
public class NotificationActivitty extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
manager.cancel(0);
// manager.cancelAll(); // Cancel all notifications for this app. from manager
}
I need to clear the notification by it's id if it's possible.
You should add a Tag to your notification and then clear you notification by providing correct id and correct tag.
You don't need notification counter if you pass the same id, because when notification sees the same id, it clears old notification and puts a new one, unless you want to show that user received multiple notifications.
private static final String TAG = "YourNotification";
private static final int NOTIFICATION_ID = 101;
private Notification notification;
public NotificationManager notificationManager;
//you can create notification with it's own id and tag, text, etc by passing
//these variables into the method (int id, String tag, ... etc)
public void createNotification()
{
notification = new Notification.Builder(context)
.setContentTitle("Content title")
.setContentText("Content text")
.setSmallIcon(R.drawable.your_small_icon)
.setLargeIcon(bitmapYourLargeIcon)
.setContentIntent(pendingIntent)
.addAction(R.drawable.icon, pendingIntentAction)
.build();
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(TAG, NOTIFICATION_ID, notification);
}
to cancel notification simply use this method:
//clears your notification in 100% cases
public void cancelNotification(int id, String tag)
{
//you can get notificationManager like this:
//notificationManage r= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(tag, id);
}
you need to add this line of code when you create your notification!!!
notification.flags |= Notification.FLAG_AUTO_CANCEL;
This will cancel the notification on click.
Further reading: Open application after clicking on Notification
** Edit, adding an extra to determine if certain notification was clicked
pIntent.putExtra("fromNotification", true);
Also you can use notification channels https://developer.android.com/develop/ui/views/notifications#ManageChannels
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);
}
Hi i want to show all the notification in a single view .. and want to update number of notification in status bar ... its updating all info but showing number always 1.. please tell me how to solve it...
#Override
public void onReceive(Context context, Intent intent)
{
//Random randGen = new Random();
//int notify_id = randGen.nextInt();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Activity.NOTIFICATION_SERVICE);
String title = intent.getStringExtra(TableUtils.KEY_TITLE);
String occasion = intent.getStringExtra(TableUtils.KEY_OCCASION);
Notification notification =
new Notification(R.drawable.icon, "Love Cardz" ,
System.currentTimeMillis());
// notification.vibrate = new long[]{100,250,300,330,390,420,500};
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.number+=1;
Intent intent1 = new Intent(context, ThemesBrowserActivity.class);
PendingIntent activity =
PendingIntent.getActivity(context, 1 , intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(context, occasion, title, activity);
notificationManager.notify(1, notification);
}
You have to keep track of the count. You could extend the Application class:
public class AppName extends Application {
private static int pendingNotificationsCount = 0;
#Override
public void onCreate() {
super.onCreate();
}
public static int getPendingNotificationsCount() {
return pendingNotificationsCount;
}
public static void setPendingNotificationsCount(int pendingNotifications) {
pendingNotificationsCount = pendingNotifications;
}
}
And you should modify the onReceive:
#Override
public void onReceive(Context context, Intent intent) {
...
int pendingNotificationsCount = AppName.getPendingNotificationsCount() + 1;
AppName.setPendingNotificationsCount(pendingNotificationsCount);
notification.number = pendingNotificationsCount;
...
}
And you could reset the count when the user open the notification:
AppName.setPendingNotificationsCount(0);
This is my code, and it works. I have only tested on old Android versions thou. I suspect on newer versions the "number" badge has been made invisible, but I haven't had the chance to test it.
void notifyMsgReceived(String senderName, int count) {
int titleResId;
String expandedText, sender;
// Get the sender for the ticker text
// i.e. "Message from <sender name>"
if (senderName != null && TextUtils.isGraphic(senderName)) {
sender = senderName;
}
else {
// Use "unknown" if the sender is unidentifiable.
sender = getString(R.string.unknown);
}
// Display the first line of the notification:
// 1 new message: call name
// more than 1 new message: <number of messages> + " new messages"
if (count == 1) {
titleResId = R.string.notif_oneMsgReceivedTitle;
expandedText = sender;
}
else {
titleResId = R.string.notif_missedCallsTitle;
expandedText = getString(R.string.notif_messagesReceivedTitle, count);
}
// Create the target intent
final Intent intent = new Intent(this, TargetActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
final PendingIntent pendingIntent =
PendingIntent.getActivity(this, REQUEST_CODE_MSG_RECEIVED, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Build the notification
Notification notif = new Notification(
R.drawable.ic_notif_msg_received, // icon
getString(R.string.notif_msgReceivedTicker, sender), // tickerText
System.currentTimeMillis()); // when
notif.setLatestEventInfo(this, getText(titleResId), expandedText, pendingIntent);
notif.number = count;
notif.flags = Notification.FLAG_AUTO_CANCEL;
// Show the notification
mNotificationMgr.notify(NOTIF_MSG_RECEIVED, notif);
}
It is also easy to update the notification later on: you just have to call the method again with new values. The number will be displayed in the notification icon badge if and only if it was greater than zero when the notification was created.
Similarily, the number badge won't be hidden (the number will, thou) if you set the number to a number that is less than 1. Maybe clearing the notification before re-showing it could fix it.
You have to keep track of the count. The increment that you're trying to perform on notif.number isn't working, since that state is unavailable (i.e. notif.number is always 0, then you increment it to 1). Keep track of number somewhere in your app(shared preferences, perhaps), and increment and store it there, then when you build the notification, set
notif.number = myStoredValueForWhatShouldShowInNumber;
Give that a try.
My problem is when I send more than one notification (from the server to the phone via c2dm), I receive all of them with all their information.
I see that I have two icons with notifications. When I click one of them is with my information (I clicked on it, I getActivity), the other is like untrue... didn't start the activity.
I read something about PendingIntent, that start activity once, but I do not know what to do.
I need to get every notification, not only the last (it's not like update).
private void incomingTestp(JSONObject json, Context context) throws JSONException {
Intent intent = new Intent(context, TestpViewActivity.class);
Testp testp = Testp.fromJSON(json);
TestpServiceUtil.save(testp);
intent.putExtra("testpId", testp.getTestpId());
sendNotification("New Testp", "update", intent, testp.getTestpId(), context);
}
private void incomingTestr(JSONObject json, Context context) throws JSONException {
Intent intent = new Intent(context, TestrViewActivity.class);
Testr Testr = Testr.fromJSON(json);
TestrServiceUtil.save(testr);
intent.putExtra("testrId", testr.getTestrId());
sendNotification("New Testr", "update", intent, report.getTestrId(), context);
}
private void sendNotification(String title, String description, Intent intent, long id, Context context) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon, title, System.currentTimeMillis());
intent.putExtra("force", true);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context.getApplicationContext(), title, description, PendingIntent.getActivity(context, requestCode++, intent, Intent.FLAG_ACTIVITY_NEW_TASK));
notification.vibrate = new long[] { 0, 200, 100 };
//notification.defaults |= Notification.DEFAULT_SOUND;
notificationManager.notify("Test", (int) id, notification);
}
I give you a little more information to know how i call this method.
try: PendingIntent.getActivity(context, requestCode++, intent, 0);
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.