I use fcm and heads up notification will show when app is open but not show when app is not open or killed.
How to handle heads up notification when app is not open?
Doc say :
With Android 5.0 (API level 21), notifications can appear in a small
floating window (also called a heads-up notification) when the device
is active (that is, the device is unlocked and its screen is on).
These notifications appear similar to the compact form of your
notification, except that the heads-up notification also shows action
buttons. Users can act on, or dismiss, a heads-up notification without
leaving the current app.
As per Doc, If you want heads-up notification you have to create your own as below :
notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
if (Build.VERSION.SDK_INT >= 21) notificationBuilder.setVibrate(new long[0]);
Don't abuse heads-up notification. See here for when to use heads-up notification:
MAX: For critical and urgent notifications that alert the user to a
condition that is time-critical or needs to be resolved before they
can continue with a particular task.
HIGH: Primarily for important communication, such as messages or chat
events with content that is particularly interesting for the user.
High-priority notifications trigger the heads-up notification display.
Additional note from HERE
Update :
To override GCM listener service :
<service android:name=".MyGcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
FCM would be :
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
Then override method :
GCM :
public class MyGcmListenerService
extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
... create your heads-up notification here.
}
FCM :
public class MyFirebaseMessagingService extends FirebaseMessagingService {
/**
* Called when message is received.
*
* #param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
... create your heads-up notification here.
}
Can't post in comment, so here it is. Try this, i had tested :
private void test() {
Intent intent;
intent = new Intent(this, SplashScreenActivity.class);
Bundle bundle = new Bundle();
bundle.putBoolean("isDisplayAlert", true);
bundle.putString("NOTIFICATION_DATA", "data");
intent.putExtras(bundle);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
new Random().nextInt(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_location)
.setContentTitle("Title")
.setContentText("Body")
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setOnlyAlertOnce(true)
.setFullScreenIntent(pendingIntent, true);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
notificationBuilder.setVibrate(new long[0]);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
Related
im referring this answer for foreground and background to receive firebase notification
--> https://stackoverflow.com/a/38451582/12553303
actually following is my doubt:----------
what if i didnt code for foreground condition(talking about push notification) still i will get notifcation when my app is in background right????-->yes
but when im on foreground state and i pushed a notification from firebase -->i wont see notification on status bar that is also okay(beacuse suppose i didnt override onmessagereceive() method)....then next i go to background state i didnt see any notification though which i sent for background
what should i do to get notification which i sent for background like going from foreground state(with no method of onmessagereceived()) to
background state??*
thanks need advice and clarification on this ...
is this even possible get that notification moving from foreground state to
background state??
code :----
override fun onMessageReceived(p0: RemoteMessage) {
super.onMessageReceived(p0)
Log.d("msg", "onMessageReceived: " + p0.getData().get("message"))
val intent = Intent(this, OrderListActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
val channelId = "Default"
val builder: NotificationCompat.Builder =NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(p0.getNotification()?.getTitle())
.setContentText(p0.getNotification()?.getBody()).setAutoCancel(true)
.setContentIntent(pendingIntent)
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId,
"Default channel",
NotificationManager.IMPORTANCE_DEFAULT)
manager.createNotificationChannel(channel)
}
manager.notify(0, builder.build())
}
any advice will be appreciated thanks
To receive messages in an Android app, Firebase Notifications contains different mechanisms when app is foreground or in background.
When the app is closed, your notifications are processed by the Google Service process, which display your notifications as required, including click action i.e.opening the app and the notification icon.
When the app is in foreground, the received messages are processed by the app.
To fix this, following are the steps to follow:-
1.Create a new class that extends FirebaseMessagingService
2.Implement the onMessageReceived() method
3.Then get the Notification object from the remoteMessage and create your own Android Notification like,
public class MyNotificationService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle(remoteMessage.getNotification().getTitle())
.setContentText(remoteMessage.getNotification().getBody())
.setSmallIcon(R.mipmap.ic_launcher)
.build();
NotificationManagerCompat manager = NotificationManagerCompat.from(getApplicationContext());
manager.notify(1, notification);
}
}
4.Then add the Service in your AndroidManifest.xml
<service android:name=”.MyNotificationService”>
<intent-filter>
<action android:name=”com.google.firebase.MESSAGING_EVENT”/>
</intent-filter>
</service>
Please help me. I created an Android application for my website.
Now I want to notify the users when I update/upload new contents to my website.
I mean to say when I update something to my webpage, the users who are using my applicationm ust get the notification that:
* "... is added to... "
* "check out now..."
I hope you understand what I am trying to say.
Sorrry for my bad English
I.e.: just like a newspaper application on adding new news to webpage.
Users get notification that "Something happens"
The easiest solution for you to add Firebase to your application.
Then you'll need Firebase Cloud Messaging Service.
compile 'com.google.firebase:firebase-messaging:11.6.2'
Add this service to your manifest
<service
android:name=".model.notifications.NotificationService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
And create your service
public class NotificationService extends FirebaseMessagingService {
#Override public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Timber.d("Message received [" + remoteMessage + "]");
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 1410, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this).setSmallIcon(R.drawable.logo)
.setContentTitle("Notification!")
.setContentText(remoteMessage.getNotification().getBody())
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.notify(1410, notificationBuilder.build());
}
}
}
If you go to Notifications panel in your Firebase dashboard, you can send instant notifications to a specific user or every user who use your app.
You can use something to make push notification such as Firebase.
here's a link you can start from here
hey all i got a tough problem and need advice. I have constructed a notification manually after recieving a FCM data payload. This is how the notification gets created both in foreground and background since its a data payload:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
String msg = remoteMessage.getData().get("message");
sendNotification(msg);
}
private PendingIntent createIntent(String msg) {
Intent intent = new Intent(this, SportsActivity.class);
Bundle b = new Bundle();
b.putString(Constants.KEY_GO_TO_TAB, Constants.KEY_DASHBOARD_HOCKEY_SCORE_TAB);
intent.putExtras(b);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
return pendingIntent;
}
private void sendNotification( String messageBody) {
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
android.support.v4.app.NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(messageBody))
.setContentText(messageBody)
.setColor(ContextCompat.getColor(this, R.color.hockey_brand))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(createIntent(messageBody));
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
it seems to function fine. The issue im having is i want the notification to NOT SHOW in when the app is in the foreground. is there not a way to do this without scanning the activity task ? as this requires a permission
i've read this article but this how to know you've went from foreground to background. also android.permission.GET_TASKS is deprecated and REAL_GET_TASKS permission is not for third party either. I simply want to know at any given time that the user is either in foreground or background so i know if i should show a notification or not. I wonder if firebase itself has something. When you send a "Notification payload" from the firebase console if the app is not in the foreground is does not show in the notification panel so there should be a way to do this.
Alternatively you can choose not to show your notification when your app is in foreground by implementing Application.ActivityLifecycleCallbacks
in your Application.
Then you can check if your app is in foreground or background.
Source
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
Yesterday Google presented at Google I/O the new notification system based on the new Firebase. I tried this new FCM ( Firebase Cloud Messaging ) with the example on Github.
The icon of the notification is always the ic_launcher despite I have declared a specific drawable
Why ?
Here below the official code for handling the message
public class AppFirebaseMessagingService extends FirebaseMessagingService {
/**
* Called when message is received.
*
* #param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
// [START receive_message]
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
sendNotification(remoteMessage);
}
// [END receive_message]
/**
* Create and show a simple notification containing the received FCM message.
*
* #param remoteMessage FCM RemoteMessage received.
*/
private void sendNotification(RemoteMessage remoteMessage) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// this is a my insertion looking for a solution
int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.myicon: R.mipmap.myicon;
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(icon)
.setContentTitle(remoteMessage.getFrom())
.setContentText(remoteMessage.getNotification().getBody())
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
Unfortunately this was a limitation of Firebase Notifications in SDK 9.0.0-9.6.1. When the app is in the background the launcher icon is use from the manifest (with the requisite Android tinting) for messages sent from the console.
With SDK 9.8.0 however, you can override the default! In your AndroidManifest.xml you can set the following fields to customise the icon and color:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/notification_icon" />
<meta-data android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/google_blue" />
Note that if the app is in the foreground (or a data message is sent) you can completely use your own logic to customise the display. You can also always customise the icon if sending the message from the HTTP/XMPP APIs.
Use a server implementation to send messages to your client and use data type of messages rather than notification type of messages.
This will help you get a callback to onMessageReceived irrespective if your app is in background or foreground and you can generate your custom notification then
atm they are working on that issue https://github.com/firebase/quickstart-android/issues/4
when you send a notification from the Firebase console is uses your app icon by default, and the Android system will turn that icon solid white when in the notification bar.
If you are unhappy with that result you should implement FirebaseMessagingService and create the notifications manually when you receive a message. We are working on a way to improve this but for now that's the only way.
edit: with SDK 9.8.0 add to AndroidManifest.xml
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="#drawable/my_favorite_pic"/>
My solution is similar to ATom's one, but easier to implement. You don't need to create a class that shadows FirebaseMessagingService completely, you can just override the method that receives the Intent (which is public, at least in version 9.6.1) and take the information to be displayed from the extras. The "hacky" part is that the method name is indeed obfuscated and is gonna change every time you update the Firebase sdk to a new version, but you can look it up quickly by inspecting FirebaseMessagingService with Android Studio and looking for a public method that takes an Intent as the only parameter. In version 9.6.1 it's called zzm.
Here's how my service looks like:
public class MyNotificationService extends FirebaseMessagingService {
public void onMessageReceived(RemoteMessage remoteMessage) {
// do nothing
}
#Override
public void zzm(Intent intent) {
Intent launchIntent = new Intent(this, SplashScreenActivity.class);
launchIntent.setAction(Intent.ACTION_MAIN);
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* R equest code */, launchIntent,
PendingIntent.FLAG_ONE_SHOT);
Bitmap rawBitmap = BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(rawBitmap)
.setContentTitle(intent.getStringExtra("gcm.notification.title"))
.setContentText(intent.getStringExtra("gcm.notification.body"))
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
if your app is in background the notification icon will be set onMessage Receive method but if you app is in foreground the notification icon will be the one you defined on manifest
Just set targetSdkVersion to 19. The notification icon will be colored.
Then wait for Firebase to fix this issue.
There is also one ugly but working way. Decompile FirebaseMessagingService.class and modify it's behavior. Then just put the class to the right package in yout app and dex use it instead of the class in the messaging lib itself. It is quite easy and working.
There is method:
private void zzo(Intent intent) {
Bundle bundle = intent.getExtras();
bundle.remove("android.support.content.wakelockid");
if (zza.zzac(bundle)) { // true if msg is notification sent from FirebaseConsole
if (!zza.zzdc((Context)this)) { // true if app is on foreground
zza.zzer((Context)this).zzas(bundle); // create notification
return;
}
// parse notification data to allow use it in onMessageReceived whe app is on foreground
if (FirebaseMessagingService.zzav(bundle)) {
zzb.zzo((Context)this, intent);
}
}
this.onMessageReceived(new RemoteMessage(bundle));
}
This code is from version 9.4.0, method will have different names in different version because of obfuscation.
write this
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/ic_notification" />
right down <application.....>
I'm triggering my notifications from FCM console and through HTTP/JSON ... with the same result.
I can handle the title, full message, but the icon is always a default white circle:
Notification screenshot
Instead of my custom icon in the code (setSmallIcon or setSmallIcon) or default icon from the app:
Intent intent = new Intent(this, MainActivity.class);
// use System.currentTimeMillis() to have a unique ID for the pending intent
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
if (Build.VERSION.SDK_INT < 16) {
Notification n = new Notification.Builder(this)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true).getNotification();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//notificationManager.notify(0, n);
notificationManager.notify(id, n);
} else {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Notification n = new Notification.Builder(this)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setLargeIcon(bm)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//notificationManager.notify(0, n);
notificationManager.notify(id, n);
}
Thought I would add an answer to this one, since my problem was simple but hard to notice. In particular I had copy/pasted an existing meta-data element when creating my com.google.firebase.messaging.default_notification_icon, which used an android:value tag to specify its value. This will not work for the notification icon, and once I changed it to android:resource everything worked as expected.