I need to write some application which will do some work in background. This application will be run from autostart and there wont be any start gui. Gui can be call from click on notification which will be showing with autostart. I worried that, when user clear notifications he lost opportunity to call this gui. My question is that is there any way to block clearing my notification by user?
Here's a notification that won't allow the user to clear it.
Notification notification = new NotificationCompat.Builder(this)
.setTicker(r.getString(R.string.app_name))
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(r.getString(R.string.app_name))
.setAutoCancel(false)
.setOngoing(true)
.build();
The setOngoing(true) call achieves this, and setAutoCancel(false) stops the notification from going away when the user taps the notification.
The notification will be cleared if the application is uninstalled or by calling Cancel or CancelAll: http://developer.android.com/reference/android/app/NotificationManager.html#cancel(int)
You might want to look into making a notification in the "running" section of the notifications. These notifications aren't cleared when the user clears them.
Use the Notification.FLAG_NO_CLEAR AND Notification.FLAG_ONGOING_EVENT. This should give you the effect you want
Though #cja answer might be correct though he is missing some few lines of codes(Notification wont show or wont display on your notification tray).
This is the complete working function :
public void createNotification() {
NotificationCompat.Builder notification = new NotificationCompat.Builder(this);
notification.setTicker( "Ticker Text" );
notification.setSmallIcon(R.drawable.ic_launcher);
notification.setContentTitle( "Content Title" );
notification.setContentText( "Content Text" );
notification.setAutoCancel( false );
notification.setOngoing( true );
notification.setNumber( ++NotificationCount );
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
notification.setContentIntent(pIntent);
notification.build();
NotificationManager nManger = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nManger.notify(NotificationID, notification.build());
}
NotificationID is int serve as your notification's ID.
you can clear it by using this :
public void clear() {
NotificationManager oldNoti = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
oldNoti.cancel( NotificationID );
}
make sure that notification.setAutoCancel( false ); is set to false so it wont be cleared when clear button is pressed or when swipe gesture is present.
few lines of codes are originally from #cja post.
cheers / happy codings...
Just add these two flags to the notification, FLAG_AUTO_CANCEL prevent notification automatically dismissed when the user touches it and FLAG_ONGOING_EVENT make it an Ongoing Notification.
notification.flags=Notification.FLAG_AUTO_CANCEL|Notification.FLAG_ONGOING_EVENT;
using this alone works perfectly for me Notification.FLAG_NO_CLEAR
along with
notification.SetOngoing(true);
notification.SetAutoCancel(false);
You want to implement a Foreground Service.
Related
I have implemented firebasse notification functionality in my chat app and everything is running fine but now while testing in Android os 8.0 and 8.1 when app is in background and if user is getting 4 or more than 4 notification then its combined in group and when user click on group then not getting intent and app is restarted.
If user tap on single notification then I am able to send him in specific screen.
I want Notification data or chat id so I can send him in specific screen but not getting any data in intent.
I have searched similar kind of question in stackoverflow but still not getting proper result.
Android: Clicking Grouped Notifications Restarts App
How to open non-launcher activity on notification group click
You can use setContentIntent to set the value of Intent like below
Intent intent = new Intent(this, SecondActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.your_notification_icon)
.setContentTitle("Notification Title")
.setContentText("Notification ")
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, mBuilder.build());
It will open SecondActivity (Replace the SecondActivity with your own activity)
I am having the same issue causing app restart in Oreo, after many tries i noticed that if when creating the notification i call .setGroup(string) the system no longer groups the notifications.I am creating the notifications from a service. This is not a solution i know but not grouping is a lesser evil than app restart.
I have this scenario when user clicks the notification then, if the app is opened/foreground I want to redirect the user to HomeActivity else redirect the user to SplashActivity as I am performing some authentication tasks there. So, what is the best and proper way to achieve this??
I know there are lot of related questions but I haven't found anything specific to my usecase
To redirect the user to a specific Activity based on your logic you can use PendingIntent.
To check a working example click here.
OR
try below code on button click.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(android.R.drawable.ic_dialog_alert);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.stackoverflow.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentIntent(pendingIntent);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
builder.setContentTitle("Notifications Title");
builder.setContentText("Your notification content here.");
builder.setSubText("Tap to view the website.");
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Will display the notification in the notification bar
notificationManager.notify(1, builder.build());
To check if your app is in the foreground or not Check out this post.
After some searching in this forum I got this post , taking some guidance from that I figured out a solution, on notification click I am redirecting every intent to HomeActivity and in onCreate() put my code to check if authentication is done or not(before setContentView()). If the authentication is not done redirect to SplashActivity and finish the current activity, otherwise continue.
As part of my assignment I want to remove a notification that has been received but not been interacted with after a certain amount of time. This means if the notification is still in the notification tray after this amount of time, the app will delete it automatically.
For foreground notifications this wasn't the issue, as I applied the following code:
void SendNotification(RemoteMessage remotemessage)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
long[] pattern = { 100, 100, 100, 100 };
var notificationBuilder = new Notification.Builder(this)
.SetVibrate(pattern)
.SetSmallIcon(Resource.Drawable.mhu2)
.SetContentTitle(remotemessage.GetNotification().Title)
.SetContentText(remotemessage.GetNotification().Body)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager)GetSystemService(Context.NotificationService);
int id = 0;
notificationManager.Notify(id, notificationBuilder.Build());
Handler handler = new Handler(Looper.MainLooper);
long delayInMilliseconds = 5000;
handler.PostDelayed(new Runnable(() => notificationManager.Cancel(id)), delayInMilliseconds);
}
When a notification is received, it will automatically be removed after 5 seconds (debugging purposes). However, as we all know, notifications are not handled the same depending on the state of the app.
This code works for foreground apps, but will never be run when the app is in the background or killed. So when the user receives a notification when the app was not opened or in the background, the notification will not be removed.
I've tried to look into this and saw partial solutions by executing code when overriding the OnDestroy/OnStop/OnPause state, but that still won't help to remove the notification when the app was never opened.
Any suggestions are greatly appreciated!
I just want to post a quick update as I've been able to solve this issue.
Android handles notification differently based on what is provided within the notification. I found out that if the notification is only build with datafields (so no notification body), the OnMessageReceived() will always be fired regardless of the state of the app. The timer that I realised will fire on foreground, background and app closed states. The only time this doesn't work is when the app is forced stopped, but in my context this won't cause issues.
I have a very strange issue, I am working on Push Notification and it was successfully implemented but when i have used BigTextStyle in Notification to show a long message in notification area with setFullScreenIntent() method then the issue coming up the Notification opening the Activity automatically which is set in PendingIntent.
If I don't use setFullScreenIntent() then notification won't opening Activity automatically the user has to tap or click on Notification to open the Activity set in PendingIntent.
So there are two codes
Without setFullScreenIntent() working fine and not opening Activity automatically:
notification = new NotificationCompat.Builder(context)
.setContentTitle("Title")
.setContentIntent(resultPendingIntent)
.setContentText(message)
.setStyle(
new NotificationCompat.BigTextStyle()
.bigText(message))
.setSmallIcon(R.drawable.ic_launcher)
.setAutoCancel(true);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(1, notification.build());
With setFullScreenIntent() also working fine but opening Activity automatically:-
notification = new NotificationCompat.Builder(context)
.setContentTitle("Title")
.setContentIntent(resultPendingIntent)
.setContentText(message)
.setStyle(
new NotificationCompat.BigTextStyle()
.bigText(message))
.setSmallIcon(R.drawable.ic_launcher)
.setFullScreenIntent(resultPendingIntent, true) //Whether true or false same result
.setAutoCancel(true);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(1, notification.build());
public NotificationCompat.Builder setFullScreenIntent (PendingIntent intent, boolean highPriority)
An intent to launch instead of posting the notification to the status
bar. Only for use with extremely high-priority notifications demanding
the user's immediate attention, such as an incoming phone call or
alarm clock that the user has explicitly set to a particular time. If
this facility is used for something else, please give the user an
option to turn it off and use a normal notification, as this can be
extremely disruptive.
On some platforms, the system UI may choose to display a heads-up
notification, instead of launching this intent, while the user is
using the device.
Parameters
intent: The pending intent to launch.
highPriority: Passing
true will cause this notification to be sent even if other
notifications are suppressed.
Found here. As you can see it immediately launches the intent. I don't really know in what case you wanted to use setFullScreenIntent()?
A notification won't automatically expand when a static notification is displayed on top (could be custom bar with wifi, bluetooth and sound control)
pass setFullScreenIntent and setContentIntent with different pending intents.
Worked for me. click on Notif will work and autolaunch will stop
I have made an app that sets notifications in the drop-down status bar of Android phones. However, there is a bug in my code (sometimes the notifications are set, sometimes they are not). I want to be able TO CHECK (in the code) IF THE NOTIFICATION IS VISIBLE TO THE USER. (i.e. can the user see the notification in the status bar?).
How can I do this? (Thanks in advance).
Sample code is greatly appreciated.
I want to be able TO CHECK (in the code) IF THE NOTIFICATION IS VISIBLE TO THE USER. (i.e. can the user see
the notification in the status bar?).
How can I do this?
You can't, sorry. Update: Now possible with Android 4.3+ http://developer.android.com/reference/android/service/notification/NotificationListenerService.html#getActiveNotifications()
However, you can always simply cancel() it -- canceling a Notification that is not on-screen is perfectly fine. Conversely, you can always safely call notify() again for the same Notification, and it too will not cause a problem if the Notification is already on-screen.
EDIT:
NotificationManager.getActiveNotifications() was added in API 23 if you don't want to use the NotificationListenerService
Just to put all together. This is how it works
To build a notification,
Notification n = new Notification.Builder(MyService.this)
.setContentTitle("Notification Title")
.setContentText("Notification Message")
.setSmallIcon(R.drawable.myicon).build();
To make a notification sound call setSound() of Notification,
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification n = new Notification.Builder(MyService.this)
.setContentTitle("Notification Title")
.setContentText("Notification Message")
.setSound(alarmSound)
.setSmallIcon(R.drawable.myicon).build();
To cancel the notification after user selected and launched the receiver Intent, call setAutoCancel(),
Notification n = new Notification.Builder(MyService.this)
.setContentTitle("Notification Title")
.setContentText("Notification Message")
.setSound(alarmSound)
.setAutoCancel(true)
.setSmallIcon(R.drawable.myicon).build();
To make sound/vibrate only once for a particular notification use Notification.FLAG_ONLY_ALERT_ONCE. With this flag, your notification will make sound only once till it gets cancelled and you can call notify() as many times as you want with the notification id. Note that if you call cancel() or if user cancelled the notification or auto cancelled, notify() call will make the notification sound again.
n.flags |= Notification.FLAG_ONLY_ALERT_ONCE; // Dont vibrate or make notification sound
Finally to put the notification on notification panel,
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(notification_id, n);
Note that notification_id here is important if you want to use the notification effectively.( to keep single sound/vibration for a notification or to cancel a specific notification).
To cancel a particular notification,
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.cancel(notification_id);
You can cancel() a notification even if it doesn't exist or you can call notify() as many times as you want with the same id. Note that calling notify with different id will create new notifications.
So, regardless of whether the notification exist or not, if you call notify() again with the correct notification_id with the Notification.FLAG_ONLY_ALERT_ONCE flag set, you can keep your notification alive without disturbing the user with repeated sounds.
You need to set an id for each notification you make.
so you make a notification ..
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notId + selectedPosition, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, rightNow.getTimeInMillis() - offset, pendingIntent);
Notification notification = new Notification(R.drawable.icon, "TVGuide Υπενθύμιση", System.currentTimeMillis());
NotificationManager manger = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
notification.setLatestEventInfo(context, "Κανάλι: " + b.getString("channel"), "Εκπομπή: " + showname, pendingIntent);
manger.notify(notId, notification);
to clear it..
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,notId, intent, 0);
pendingIntent.cancel();
and to check if active..( existAlarm returns null if no pending intent available)
public PendingIntent existAlarm(int id) {
Intent intent = new Intent(this, alarmreceiver.class);
intent.setAction(Intent.ACTION_VIEW);
PendingIntent test = PendingIntent.getBroadcast(this, id + selectedPosition, intent, PendingIntent.FLAG_NO_CREATE);
return test;
}
So everything comes down to initialize an ID for each notification and how you make it unique.
A new method is introduced to the NotificationManager class in API 23:
public StatusBarNotification[] getActiveNotifications()
There exists a flag for that.
Notification notification = new Notification(icon, tickerText, when);
notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
FLAG_ONLY_ALERT_ONCE:
...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.
Although, the notification will blink when it is sent again, but there won't be any sound or vibration.
It's possible now to check notifications outstanding in android 4.3 upwards
See here:
http://developer.android.com/reference/android/service/notification/NotificationListenerService.html#getActiveNotifications()
It seems that from Android M (API 23) it is possible to get your process like that, without using NotificationListenerService nor requiring additional permissions:
notificationManager.getActiveNotifications()
As of Android Marshmallow (API 23), you can recover a list of active notifications posted by your app. This NotificationManager method is getActiveNotifications(). More info here: https://developer.android.com/reference/android/app/NotificationManager.html#getActiveNotifications()