In the Firebase Cloud Messaging documentation, nothing mentioned about the notifications with big view/expanded layout.
How should I display big view notifications when app is background? Creating custom notification in FirebaseMessagingService's onMessageReceived seems not possible according to this faq:
When your app is in the background, notification messages are displayed in the system tray, and onMessageReceived is not called. For notification messages with a data payload, the notification message is displayed in the system tray, and the data that was included with the notification message can be retrieved from the intent launched when the user taps on the notification.
Send the notification you want to see using the data object. You can basicly put everything you want in the data object and always receive it at the onMessageReceived method. Here's an example.
public class AppFireBaseMessagingService extends FirebaseMessagingService {
private final static int REQUEST_CODE = 1;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
if (data == null) return;
if (data.containsKey("title") && data.containsKey("message")) {
showNotification(data.get("title"), data.get("message"));
}
}
private void showNotification(String title, String body) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle(title)
.setSmallIcon(R.drawable.notification_icon);
if (body != null && !body.isEmpty()) {
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(body));
builder.setContentText(body);
}
Intent intent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
builder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification n = builder.build();
n.defaults = Notification.DEFAULT_ALL;
notificationManager.notify(0, n);
}
}
Related
I am working chat application. I want to show custom push Notification when message receives, when app is open and closed (not destroyed or killed) notification are received, below code is working fine, but when app is killed or destroyed from background custom push notification is not received in oreo and above
Here is code I Used
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
try {
context = getApplicationContext();
Map<String, String> data = remoteMessage.getData();
if ("message".equals(data.get("pushNotificationAction"))){
System.out.println("message");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),
0, intent, 0);
String mediatype = data.get("mediaType");
String mesageType= data.get("messageType");
String channel_id = createNotificationChannel(getApplicationContext());
mBuilder = new NotificationCompat.Builder(getApplicationContext(),channel_id)
.setSmallIcon(R.drawable.kisan_smoll_logo1)
.setCustomBigContentView(contentViewBig)
.setCustomContentView(contentViewBig)
.setContentIntent(contentIntent)
.setContentTitle(data.get("messageText"))
.setWhen(when)
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(NotificationManager.IMPORTANCE_MAX)
.setAutoCancel(true);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}catch(Exception e){
e.printStackTrace();
}
Sending JSON from server is below:
{
"message":{
"to": "FCMID",
"data" : {
"body" : "This is a Message!",
"title" : "Notifiation Message"
"mediaType":"IMAGE",
"messageType":"chat",
}
}
}
By sending data from server custom Fcm push notification is received in android when app is open, but when app is swipe from recent notifications are not received
The FCM is working fine and notification came on device when app is in foreground state, and when tapped on notification, it is redirecting to my specified Activity, so it is working fine.
But my challenge is when the notification comes when app is in background state and when tapped, it redirects to Default Activity but I want to navigate to specified activity.
Here is MyFirebaseMessagingService class:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
private String title, messageBody;
/**
* 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) {
// [START_EXCLUDE]
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
if (remoteMessage.getData() != null && remoteMessage.getData().size() > 0) {
title = remoteMessage.getData().get("title");
if (TextUtils.isEmpty(title)) title = "Bocawest";
messageBody = remoteMessage.getData().get("message");
}
handleNow();
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
}
// 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.
if (!TextUtils.isEmpty(messageBody))
sendNotification(title, messageBody);
//sendNotification(remoteMessage.getNotification().getBody());
Intent intent = new Intent();
intent.setAction("com.android.bocawest");
sendBroadcast(intent);
}
// [END receive_message]
/**
* Handle time allotted to BroadcastReceivers.
*/
private void handleNow() {
Log.d(TAG, "Short lived task is done.");
}
/**
* Create and show a simple notification containing the received FCM message.
*
* #param messageBody FCM message body received.
*/
private void sendNotification(String title, String messageBody) {
PendingIntent pendingIntent;
if (SharedPreference.getBoolean(getApplicationContext(), getApplicationContext().getResources().getString(R.string.sp_isLoginIN))) {
Intent intent = new Intent(this, NotificationsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
} else {
Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
String channelId = getString(R.string.default_notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Bocawest",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0, notificationBuilder.build());
}
}
Note : NotificationsActivity is my specified activity.
HomeActivity is Default Activity
I know there are lot of similar questions but I haven't found anything specific to my usecase.
Please Help me.
#Laxman parlapelly as per Firebase standered when your app receive notification in background and user tap on notification then it will open default activity only.
If you want to open your specified activity then you have to pass through your default activity only.
For example in your case when user tap on notification it will open your Home activity and from oncreate method of HomeActivity you need to open NotificationsActivity(along with bundle incase needed)
When
Notification is tapped when app is in background then onCreate() method of HomeActivity will be called so with in that you can write code to open Notification Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
animLay = findViewById(R.id.root_lay_la);
Intent intent = new Intent(this,NotificationActivity.class);
//intent.putExtra("KEY",getIntent().getStringExtra("data")); if u need to pass data
startActivity(intent);
}
if(SharedPreference.getBoolean(getApplicationContext(), getApplicationContext().getResources().getString(R.string.sp_isLoginIN))) write this logic in HomeActivity(in onCreate() before setContentView()) so every time user will be re-directed to HomeActivity and if the above condition satisfies the user will be redirected again to NotificationsActivity else will continue with HomeActivity
check - Navigate to different activities on notification click
this works for me
- just add the code below inside onMessageReceived()
Intent intent = new Intent(this, NotificationsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "111")
.setSmallIcon(R.drawable.logo)
.setContentTitle(getString(R.string.yhnn))
.setContentText(title)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setSound(sound)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(5, builder.build());
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
I am implementing push notifications on Android. The problem comes when I want to update my notifications. I would like to stack up notifications so that if a notification is visible I simply update it and do this.
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
But every time I receive a notification ++numMessages is set back to 0 before being summed up. I need it to sum up from where it was left if there is a notification on the screen. Here is the code:
//Class is extending GcmListenerService
public class GCMPushReceiverService extends GcmListenerService {
//variables for message 1,on receiving job applications
String name;
String lastname;
String jobtypename;
String kasualjobdatetimepostedat;
String kasualjobcount;
int numMessages;
//This method will be called on every new message received
#Override
public void onMessageReceived(String from, Bundle data) {
//Getting the message from the bundle
String message = data.getString("message");
String messageid = data.getString("messageid");
if(messageid.compareTo("1")==0){
name=data.getString("firstname");
lastname=data.getString("lastname");
jobtypename=data.getString("jobtype");
kasualjobdatetimepostedat=data.getString("kasualjobdatetimepostedat");
}
else
{
kasualjobcount=data.getString("kasualjobcount");
}
//Displaying a notification with the message
sendNotification(message, messageid);
}
//This method is generating a notification and displaying the notification
private void sendNotification(String message,String messageid) {
Intent intent = new Intent(this, Main_Activity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestCode = 0;
PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Log.d("notificationid", String.valueOf(messageid));
if(messageid.compareTo("2")==0) {//messages to do with jobs around 2
String messageionkasualjobscount="There are "+kasualjobcount+" new jobs around you";
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this);
noBuilder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("KasualJobs2")
.setContentText(messageionkasualjobscount)
.setAutoCancel(true)
.setContentIntent(pendingIntent).setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(2, noBuilder.build()); //messageid = ID of notification
}else{//messages to with users applying for job 1
String messageionkasualjobapplication=name+ " "+ lastname+" has applied for the "+jobtypename+" you posted on "+kasualjobdatetimepostedat;
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this);
noBuilder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("KasualJobs1")
.setContentText(messageionkasualjobapplication)
.setAutoCancel(true).setNumber(++numMessages)
.setContentIntent(pendingIntent).setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, noBuilder.build()); //messageid = ID of notification
}
}
}
In general, you should not expect your field values to persist across multiple calls to onMessageReceived, since the service might have been killed by the OS to free up memory.
I suggest storing your messages in a database. Whenever you receive a new message, insert it into the database, and delete it when the user reads it. Then you can easily query how many unread messages there are.
I suggest you to use FCM instead of GCM (because GCM will no longer used).
And to update notifications use sqlite database for storing the notifications with date & time. clear the notification when read & also delete it from database.
I implemented Google Cloud Messaging in my Android app. When I send a message with JSON while I have opened the app, it acts different than when I have the app closed.
When I have the app open, and receive the notification, it starts the intent I want it to start. When I have the app closed when i receive the notification, and I click on the notification, it opens the Main intent. How can I say which intent it needs to open when I have closed my app and receive the push notification?
The code in MyGcmListenerService
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
File fileDir, file;
String filename, filestring;
/**
* Called when message is received.
*
* #param from SenderID of the sender.
* #param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
#Override
public void onMessageReceived(String from, Bundle data) {
Bundle notification = data.getBundle("notification");
String title = notification.getString("title");
String naam = notification.getString("naam");
String nfcId = notification.getString("nfcId");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Title: " + title);
Log.d(TAG, "Naam: " + naam);
Log.d(TAG, "nfcId: " + nfcId);
if (from.startsWith("/topics/")) {
} else {
filename = "gegevensOverledene";
ReadWriteFile readWriteFile = new ReadWriteFile(getApplicationContext());
readWriteFile.writeFileOverledene(filename, naam);
}
sendNotification(title, naam, nfcId);
}
/**
* Create and show a simple notification containing the received GCM message.
*/
private void sendNotification(String title, String naam, String nfcId) {
Intent intent = new Intent(this, PinLoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("naam", naam);
intent.putExtra("nfcId",nfcId);
intent.putExtra("Class",NieuweOverledeneActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(naam)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
The JSON I send, note that I left out the token_mobile on purpose
{
"to": "TOKEN_MOBILE****************",
"notification": {
"title": "Nieuwe overledene",
"body": "Henk",
"naam": "Henk",
"nfcId": "80-40-A3-4A-C2-D6-04"
}
}
You are sending a notification message. See more on how notification messages are to be handled here.
When your app is in the foreground notification messages are passed to your onMessageReceived callback. There you can decide what should be done with the received message, eg: generate and display a notification or sync with your app server or whatever.
When your app is in the background notification messages automatically generate notifications based on the properties passed in the "notification" object of your downstream message request, onMessageReceived is not called in this case. If you look at the reference docs for notification messages you will see a field named click_action you can use this to define what Activity is launched when the automatically generated notification is tapped:
On Android, if this is set, an activity with a matching intent filter
is launched when user clicks the notification.
If this is not set the main Activity is launched, which is what you are seeing now.
Note: This behaviour is only for Notification Messages, if you send data only messages then all sent messages will result in onMessageReceived being called.
check Following
/**
* Create and show a simple notification containing the received GCM message.
*/
private void sendNotification(String title, String naam, String nfcId) {
//Create the intent according to your condition and pass it to pendingintent.
Intent intent = new Intent(this, PinLoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("naam", naam);
intent.putExtra("nfcId",nfcId);
intent.putExtra("Class",NieuweOverledeneActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(naam)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}