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);
Related
I successfully created an activity which starts a service which by turn shows a notification like this
public int onStartCommand(Intent intent, int flags, int startId){
String notificationText = "working"
myNotification = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle("test")
.setContentText(notificationText)
.setTicker("Notification!")
.setWhen(System.currentTimeMillis())
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher)
.build();
//FOLLOWING TECHNIQUE IS DEPRECATED
/* PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
myNotification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); */
myNotification.flags |= Notification.FLAG_NO_CLEAR;
myNotification.flags = Notification.FLAG_ONGOING_EVENT;
notificationManager.notify(1, myNotification);
return START_STICKY;
}
I know there are other questions related to this one BUT they all use setLatestEventInfo which is deprecated
And this is what I call from another activity:
protected void beginBackgroundSer(){
intentService = new Intent(this, Service.class);
intentService.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
this.startService(intentService);
}
So what I'd like is to resume the activity whenever I click the notification by non-deprecated methods. Thank you very much for your help.
You can create a notification by using the following steps.
Create a notification id for the future reference to update the notification by notification manager.
// Notification ID to allow for future updates
private static final int MY_NOTIFICATION_ID = 1;
Create the text elements for the notification.
// Notification Text Elements
private final CharSequence tickerText = "This is a Really, Really, Super Long Notification Message!";
private final CharSequence contentTitle = "Notification";
private final CharSequence contentText = "You've Been Notified!";
Define the notification Action elements i.e. when the user clicks on the view in the notification drawer what action happens? We use intents for handling this.
// Notification Action Elements
private Intent mNotificationIntent;
private PendingIntent mContentIntent;
You can also define sound and vibration for this notification.
// Notification Sound and Vibration on Arrival
private Uri soundURI = Uri
.parse("android.resource://com.examples.Notification.StatusBarWithCustomView/"
+ R.raw.alarm_rooster);
private long[] mVibratePattern = { 0, 200, 200, 300 };
Create the notification using the Notification.Builder class. Do this in your onCreate()
mNotificationIntent = new Intent(getApplicationContext(),
YourActivity.class);
mContentIntent = PendingIntent.getActivity(getApplicationContext(), 0,
mNotificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
// Build the Notification
Notification.Builder notificationBuilder = new Notification.Builder(
getApplicationContext())
.setTicker(tickerText)
.setSmallIcon(android.R.drawable.stat_sys_warning)
.setAutoCancel(true)
.setContentIntent(mContentIntent)
.setSound(soundURI)
.setVibrate(mVibratePattern)
.setContent(mContentView);
// Pass the Notification to the NotificationManager:
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(MY_NOTIFICATION_ID,
notificationBuilder.build());
From the documentations
public NotificationCompat.Builder setContentIntent (PendingIntent intent) - Supply a PendingIntent to send when the notification is clicked. If you do not supply an intent, you can now add PendingIntents to individual views to be launched when clicked by calling RemoteViews.setOnClickPendingIntent(int,PendingIntent). Be sure to read Notification.contentIntent for how to correctly use this.
So you can use setContentIntent(PendingIntent intent) method something like
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
myNotification = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle("test")
.setContentText(notificationText)
.setTicker("Notification!")
.setWhen(System.currentTimeMillis())
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(contentIntent) //added this new line
.build();
notificationManager.notify(1, myNotification);
I wanted to create something like an instant messaging application. How do I display multiple messages all in one notification? I can create a notification that appear when user receive a single notification. But when the user receive more than one message how can I update the notification with the previous message? Should I save the messages into a database and display it out if the user did not cancel the notification? Or is there any other way that I can handle this?
Below is my notification code.
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, "IMTest- A new event is created" , when);
Intent notificationIntent = new Intent(context, IM_Chat.class);
notificationIntent.putExtra("topicId", topicId);
notificationIntent.putExtra("sender", sender);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 1, notificationIntent, Intent.FLAG_ACTIVITY_MULTIPLE_TASK | PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(context, topicName, "A new event ["+eventName+"] is added in "+topicName, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.ledARGB |= 0xff0000ff;
notification.ledOffMS |= 1000;
notification.ledOnMS |= 300;
notificationManager.notify(CommunitiesappConstant.NOTIFICATION_ID, notification);
You can update notification using same id and builder
http://developer.android.com/guide/topics/ui/notifiers/notifications.html#Updating
private NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
private mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//Different Id's will show up as different notifications
private int mNotificationId = 1;
//Some things we only have to set the first time.
private boolean firstTime = true;
private updateNotification(String message, int progress) {
if (firstTime) {
mBuilder.setSmallIcon(R.drawable.icon)
.setContentTitle("My Notification")
.setOnlyAlertOnce(true);
firstTime = false;
}
mBuilder.setContentText(message)
.setProgress(100, progress, true);
mNotificationManager.notify(mNotificationId, mBuilder.build());
}
I am sending notification depending on some logic.
public class DbAdapter_Assignment extends DbAdapter {
public DbAdapter_Assignment(Context context) {
super(context);
}
public void deleteUnassignedTask(Assignment[] assignments)
{
//some logic
sendNotification(String a. String b);
}
private void triggerNotification(String s, String id)
{
CharSequence title = "TASK UNASSIGNED";
CharSequence message = s;
NotificationManager notificationManager;
notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.checkno, s, System.currentTimeMillis());
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
// No. 1 solution
PendingIntent pendingIntent = PendingIntent.getActivity(context, Integer.parseInt(id), null, PendingIntent.FLAG_UPDATE_CURRENT);
// -----------
// No. 2 solution
Intent notificationIntent = new Intent(context, MyTask.class);
notificationIntent.putExtra("EmpID", Functions.getLoginEmpID(context));
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP );
PendingIntent pendingIntent = PendingIntent.getActivity(context,
Integer.parseInt(id), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// ----------------
notification.setLatestEventInfo(context, title, message, pendingIntent);
notificationManager.notify(Integer.parseInt(id), notification);
}
}
No. 1 solution is working. the thing I want to add is if click on that notification, go to MyTask class. So I tried No. 2 solution and IT"S NOT WORKING for me. It doesn't show any notification if do no. 2 solution. What am I missing? Is ir because of the class is not an activity or servise ?
Your Notification looks right to me.
I haven't tried to create a Notification outside of a class that extends Activity, but I would assume if you can access the NotificationManager then you should be able to do it.
Does the class you're pointing the PendingIntent to extend Activity?
Could there be a problem in the Activity that your PendingIntent is using?
Is that Activity in the AndroidManifest.xml?
I simply want to start and stop the sync icon that is in the status bar. I thought it would be a simple call using NotificationManager, but I cannot find the documentation or sample Q&A on the web or SO.
I found my answer ...
http://libs-for-android.googlecode.com/svn-history/r46/trunk/src/com/google/android/accounts/AbstractSyncService.java
This shows how to set and cancel the stat_notify_sync icon.
private void showNotification(String authority) {
Object service = getSystemService(NOTIFICATION_SERVICE);
NotificationManager notificationManager = (NotificationManager) service;
int icon = android.R.drawable.stat_notify_sync;
String tickerText = null;
long when = 0;
Notification notification = new Notification(icon, tickerText, when);
Context context = this;
CharSequence contentTitle = "mobi"; //createNotificationTitle();
CharSequence contentText = "bob"; //createNotificationText();
PendingIntent contentIntent = createNotificationIntent();
notification.when = System.currentTimeMillis();
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notificationManager.notify(mNotificationId, notification);
}
private void cancelNotification() {
Object service = getSystemService(NOTIFICATION_SERVICE);
NotificationManager nm = (NotificationManager) service;
nm.cancel(mNotificationId);
}
To get an animated sync icon you can use android.R.drawable.ic_popup_sync icon. For instance, using the more recent notification builder, you'd use something like:
Notification notification = new NotificationCompat.Builder(mContext)
.setContentTitle("my-title")
.setContentText("Loading...")
.setSmallIcon(android.R.drawable.ic_popup_sync)
.setWhen(System.currentTimeMillis())
.setOngoing(true)
.build();
Thanks for your example, it saved me some time. I created a static method in my Application so I can easily turn the icon on/off from anywhere in my code. I still can't get it to animate though.
In MyApplication.java:
private static Context context;
private static NotificationManager nm;
public void onCreate(){
context = getApplicationContext();
nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
...
}
public static void setNetworkIndicator(boolean state) {
if (state == false) {
nm.cancel(NETWORK_ACTIVITY_ID);
return;
}
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
Notification n = new Notification(android.R.drawable.stat_notify_sync, null, System.currentTimeMillis());
n.setLatestEventInfo(context, "SMR7", "Network Communication", contentIntent);
n.flags |= Notification.FLAG_ONGOING_EVENT;
n.flags |= Notification.FLAG_NO_CLEAR;
nm.notify(NETWORK_ACTIVITY_ID, n);
}
And then from anywhere in my application:
MyApplication.setNetworkIndicator(true);
MyApplication.setNetworkIndicator(false);
I want to put an icon in the status bar when ever my application is running, including when it is running in the background. How can I do this?
You should be able to do this with Notification and the NotificationManager. However getting a guaranteed way to know when your application is not running is the hard part.
You can get the basic functionality of what you are desiring by doing something like:
Notification notification = new Notification(R.drawable.your_app_icon,
R.string.name_of_your_app,
System.currentTimeMillis());
notification.flags |= Notification.FLAG_NO_CLEAR
| Notification.FLAG_ONGOING_EVENT;
NotificationManager notifier = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
notifier.notify(1, notification);
This code must be somewhere where you are sure will get fired when your application starts. Possibly in your application's custom Application Object's onCreate() method.
However after that things are tricky. The killing of the application can happen at anytime. So you can try to put something in the onTerminate() of the Application class too, but it's not guaranteed to be called.
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE)).cancel(1);
will be what is needed to remove the icon.
For new API you can use NotificationCompat.Builder -
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Title");
Intent resultIntent = new Intent(this, MyActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotifyMgr.notify(NOTIFICATION_ID, notification);
It will show as long as your application is running and someone manually closes your application. You can always cancel your notification by calling -
mNotifyMgr.cancel(NOTIFICATION_ID);
Take a look at the Dev Guide "Creating Status Bar Notifications".
One way to achieve the goal of keeping the icon there only when the application is running is to initialize the notification in onCreate() and call cancel(int) in your onPause() method only if isFinishing() returns true.
An example:
private static final int NOTIFICATION_EX = 1;
private NotificationManager notificationManager;
#Override
public void onCreate() {
super.onCreate();
notificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.notification_icon;
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context = getApplicationContext();
CharSequence contentTitle = "My notification";
CharSequence contentText = "Hello World!";
Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle,
contentText, contentIntent);
notificationManager.notify(NOTIFICATION_EX, notification);
}
#Override
protected void onPause() {
super.onPause();
if (isFinishing()) {
notificationManager.cancel(NOTIFICATION_EX);
}
}
It really works.
I created a method out of the example above:
private void applyStatusBar(String iconTitle, int notificationId) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(iconTitle);
Intent resultIntent = new Intent(this, ActMain.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_NO_CLEAR|Notification.FLAG_ONGOING_EVENT;
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotifyMgr.notify(notificationId, notification);}
It should be called like: applyStatusBar("Statusbar Test", 10);