I'm using this code to create a Heads Up notification.
private static void showNotificationNew(final Context context,final String title,final String message,final Intent intent, final int notificationId, final boolean isHeaderNotification) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context.getApplicationContext())
.setSmallIcon(R.drawable.prime_builder_icon)
.setPriority(Notification.PRIORITY_DEFAULT)
.setCategory(Notification.CATEGORY_MESSAGE)
.setContentTitle(title)
.setContentText(message)
.setWhen(0)
.setTicker(context.getString(R.string.app_name));
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
notificationBuilder.setContentText(message);
if(isHeaderNotification) {
notificationBuilder.setFullScreenIntent(fullScreenPendingIntent, false);
}
notificationBuilder.setContentIntent(fullScreenPendingIntent);
notificationBuilder.setAutoCancel(true);
Notification notification = notificationBuilder.build();
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(notificationId, notification);
}
The thing is, notification should appear occupying a good part of top screen to call user attention, but after a couple seconds it should dismiss and a normal notification should appear.
But this code doesn't do that. The notification stay occupying all the top screen until user dismiss it.
I'm thinking in create another normal notification with same ID after a couple of seconds using Handler, but I want to know if there is a better way to do this.
Follow an example of WhatsApp, simulating the behavior I want.
The issue is caused because you use setFullScreenIntent:
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.
Also as explained in this answer you should use setVibrate to make Heads-up work.
This is an example of working Heads-up notification:
private static void showNotificationNew(final Context context, final String title, final String message, final Intent intent, final int notificationId) {
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context.getApplicationContext())
.setSmallIcon(R.drawable.small_icon)
.setPriority(Notification.PRIORITY_HIGH)
.setContentTitle(title)
.setContentText(message)
.setVibrate(new long[0])
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(notificationId, notificationBuilder.build());
}
Related
I know this question seems duplicate, but for my requirement, I have searched many posts online, but nothing worked for me.
My requirement
I'm using the Firebase to get the push notifications. When app was opened means everything working fine but my problem is, app is in background/closed if any push notification came means i want to open the particular activity or fragment when clicking on that notification, but it always opening the launcher/main activity.
For this, I have tried the following scenarios
Scenario 1
Used the bundle to transfer notification data from FirebaseMessagingService to the launcher/Main activity and based on the bundle data i'm redirecting to the particular activity/fragment
Scenario 2
By using Sharedpreference
Scenario 3
By using intent.putExtra
following the above scenarios everything working fine when app was opened but if my app was closed means it always redirecting to the main/launcher activity
My code
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("reqTo", messageBody);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
So, does anyone know how to open the particular activity/Fragment when clicking on the Firebase push notification when the app is closed.
public void showNotificationMessage(final String title, final String message, Intent intent) {
// Check for empty push message
if (TextUtils.isEmpty(message))
return;
// notification icon
final int icon = R.drawable.logo;
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
mContext,
0,
intent,
PendingIntent.FLAG_CANCEL_CURRENT
);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
mContext);
final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
+ "://" + mContext.getPackageName() + "/raw/notification");
showSmallNotification(mBuilder, icon, title, message, resultPendingIntent, alarmSound);
playNotificationSound();
}
private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, PendingIntent resultPendingIntent, Uri alarmSound) {
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.addLine(message);
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(inboxStyle)
.setSmallIcon(R.drawable.logo)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Config.NOTIFICATION_ID, notification);
}
private void showBigNotification(Bitmap bitmap, NotificationCompat.Builder mBuilder, int icon, String title, String message, PendingIntent resultPendingIntent, Uri alarmSound) {
NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
bigPictureStyle.setBigContentTitle(title);
bigPictureStyle.setSummaryText(Html.fromHtml(message).toString());
bigPictureStyle.bigPicture(bitmap);
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(bigPictureStyle)
.setSmallIcon(R.drawable.logo)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Config.NOTIFICATION_ID_BIG_IMAGE, notification);
}
You can check app closed or not like this
if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) {
This is very similar to my answer given here: https://stackoverflow.com/a/41441631/1291714
In summary though, you need to use Firebase Cloud Messaging and not Firebase Notifications in order to receive a message in the background and do custom processing. You need to send "data" messages to the client and then in your service, you will then always receive the callback, whether the app is in the foreground or background.
With Firebase Notifications, you will only receive the callback when the app is in the Foreground. When the app is in the background, the system will handle and display the notification for a user. You won't be able to customise this notification to open up a different intent.
Read more here: https://firebase.google.com/docs/notifications/android/console-audience
I need display notifications when my server return specific values. I have a service running on android and taskschedule running every time sending request to server, when the server return positive value i need display message on celular display, similar receive message of whatsapp (display icon and notification on display). Anyone have a sample?
I trying this:
PendingIntent resultPendingIntent = PendingIntent.getActivity(
this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
But my application is running as a service.
Please use Using Service to run background and create notification
private void processStartNotification() {
// Do something. For example, fetch fresh data from backend to create a rich notification?
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("Scheduled Notification")
.setAutoCancel(true)
.setColor(getResources().getColor(R.color.colorAccent))
.setContentText("This notification has been triggered by Notification Service")
.setSmallIcon(R.drawable.notification_icon);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
NOTIFICATION_ID,
new Intent(this, NotificationActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
builder.setDeleteIntent(NotificationEventReceiver.getDeleteIntent(this));
final NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(NOTIFICATION_ID, builder.build());
}
Short version:
I want to create a notification that is uninterruptible by all other notifications, SMS messages, etc until the user clears it.
Long version:
I'm using Firebase Cloud Messaging to send alerts to my phone. Messages are handled based on the topic, and I need to make the "alarm" messages repeat continuously until the notification is cleared by the user. This is currently accomplished by setting the notification with FLAG_INSISTENT, which loops the sound.
The problem is the insistent "alarm" notification is permanently stopped when a different notification or SMS comes through.
I would like to ignore all new notifications, or restart the alarm after the new notification plays. I've searched for a couple hours and tried several flags and settings, but can't figure out how to do it.
Here is the code I'm using to handle FCM messages and set the notifications:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getData() != null){
String messageTopic= remoteMessage.getFrom();
String messageTitle = remoteMessage.getData().get("title");
String messageBody = remoteMessage.getData().get("message");
if (messageTopic.equals("/topics/news")) {
Intent intent = new Intent(this, MainScreenActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri soundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_news)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
.setPriority(Notification.PRIORITY_MAX);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(30548, notificationBuilder.build());
}
else if (messageTopic.equals("/topics/alarm")) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.example.com/alarm.php"));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_alarm)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
.setPriority(Notification.PRIORITY_MAX);
Notification mNotification = notificationBuilder.build();
mNotification.flags |= Notification.FLAG_INSISTENT;
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(30549, mNotification);
}
}
}
I may be able to prevent my own notifications from interrupting the alarm by ignoring them when the alarm notification ID (30549) is active (or create the new notification and then create the alarm again). However, SMS and notifications from other programs will still interrupt, so that wouldn't be a perfect solution.
I don't think you'll have luck with this, unfortunately. Android will not let you have a notification that takes full priority from my understanding.
However, in the Firebase console when you go to the notifications section and click advanced you can set the priority of a notification to High and set a sound.
Since it looks like you're writing the notification programmatically and setting priority to Max this will achieve the same affect.
Setting priority to high, from Google's documentation:
When a high-priority notification arrives (see right), it is presented to users for a short period of time with an expanded layout exposing possible actions.
After this period of time, the notification retreats to the notification shade. If a notification's priority is flagged as High, Max, or full-screen, it gets a heads-up notification
Also check out this SO for someone who's notification wouldn't go away when they wanted it to
here
On lollipop, If the user has a pin set then some notifications aren't able to be swiped away. they act like a persistent notification when attempting to be dismissed.
Some apps notifications are able to be swiped away on the lockscreen without unlocking.
I have only tested this with hide sensitive notification content, does a flag set change this ability?
How do I achieve this?
This flag makes your notification stick:
Notification.FLAG_ONGOING_EVENT;
If you leave it out you can remove it. If you put it in, it sticks.
FYI: How I make my notifications:
//These are parameters for setting up the tag in the tray
private static final String NOTIFICATION_ID_TAG="notificationID";
private static final int NOTIFICATION_ID=123456;
public void createNotification() {
// Prepare intent which is triggered if the
// notification is selected
Intent intent = new Intent(this, MainActivity_Host.class);
intent.putExtra(NOTIFICATION_ID_TAG, NOTIFICATION_ID);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
// Build notification
Notification noti = new Notification.Builder(this)
.setContentTitle("Service Running")
.setContentText("The service is running").setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pIntent)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//THIS FLAG MAKES THE NOTIFICATION STICK = YOU CAN'T SWIPE IT AWAY... IF YOU LEAVE IT OUT YOU CAN REMOVE THE NOTIFICATION
noti.flags |= Notification.FLAG_ONGOING_EVENT;
notificationManager.notify(NOTIFICATION_ID, noti);
}
This is how you can remove the notification from within the code:
//Erase the notification that we set up when the service started
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(NOTIFICATION_ID);
As you see, you can get the notification from the NotificationManager by the NOTIFICATION_ID you used to make it. This is just a number i made up.
I was wondering if anyone has some experience with with this type of Notification.
In my use case I want to trigger a notification from my Service and than it should open a fullscreen video. The method setFullScreenIntent look just the right thing for this problem because in the documentation it writes:
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.
So it says it works like an incoming phone call. That means even if my phone is asleep I should get to see the notification in full screen.
But in my case I just get the heads-up notification and if I click on it it opens the activity. Even thought in the docs they mention something about this behavior ...
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.
... I want to know how to automatically open the activity when the notification is triggered. Just like the incoming phone call screen.
This is my code from the service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent("android.intent.category.LAUNCHER");
intent.setClassName("com.example.test",
"com.example.test.VideoActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(contentIntent)
.setContentTitle("Video")
.setContentText("Play video")
.setFullScreenIntent(contentIntent, true);
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
return Service.START_STICKY;
}
try to notify notification with setFullScreenIntent at onCreate
#Override
public int onCreate() {
Intent notificationIntent = new Intent("android.intent.category.LAUNCHER");
intent.setClassName("com.example.test",
"com.example.test.VideoActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(contentIntent)
.setContentTitle("Video")
.setContentText("Play video")
.setFullScreenIntent(contentIntent, true);
NotificationManager mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
}
Try removing
.setContentIntent(contentIntent)