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());
}
Related
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());
AT this moment I achive to get Push Notifications (Firebase) to my client.
I followed the instructions onf firebase.
Now, as the app is a message client, I'm receiving a lot of pushes (meanwhile the app is ni background and foreground).
What I tried (and found here: https://developer.android.com/training/wearables/notifications/stacks.html)
So my code, right now is:
public class FCMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Logger.d("Notification Body:" + remoteMessage.getNotification().getBody()
+ "\n DATA:" + remoteMessage.getData().toString());
String jid = remoteMessage.getData().get("jid");
sendNotification(remoteMessage.getNotification().getBody(), jid);
}
private void sendNotification(String messageBody, String jid) {
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);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher_chv)
.setContentTitle(getString(R.string.notification_title))
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
.setGroup(jid);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
AS you can see, I receive in data bundle, the parameter "jid", that identifies the user who send the message. So I use it to try to stak all theis messages, and at the end , have 1 (stacked)notification(s) for every jid.
But, the notifications don't stack when the app is in Background, even more..it launches the notications that where stacked before.
IS there any work around to solve it?
Log of what I receive from notification push:
23304-17215 D/ChatListRealmAdapter: ║ Notification Body:Ana ha enviado un mensaje
23304-17215 D/ChatListRealmAdapter: ║ DATA:{'jid':'ana1234#domain.com'}
I have implemented push by firebase.
I'm sending notifications but I am getting status of "Failed". When I send notification to all devices it is marking as completed but I am still not getting messages in device.
Even when I send messages to single devices it will also show failed and will not receive notification on device.
The code is
private static final String TAG = "StartingAndroid";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//It is optional
Log.e(TAG, "From: " + remoteMessage.getFrom());
Log.e(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
}
//This method is only generating push notification
private void sendNotification(String title, String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, 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(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
Your sender ID mismatched or you have entered incorrect project ID in your Application.
Looking at logs, I think you are sending to specific devices via registration id but we see an error with mismatched sender id.Please check that these registration ids are valid and apply to the correct app.
I have 3 types of notifications in android.Audio/Video call and msg. How to differentiate based on notification type and open different activity on different notification. THis is hoW I open activity on click of notification.
private void sendNotification(long when,String msg) {
String notificationContent ="Notification Content Click Here to go more details";
String notificationTitle ="This is Notification";
//large icon for notification,normally use App icon
Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
int smalIcon =R.drawable.hcp;
String notificationData="This is data : "+msg;
/*create intent for show notification details when user clicks notification*/
Intent intent =new Intent(getApplicationContext(), NotificationDetailsActivity.class);
intent.putExtra("DATA", notificationData);
/*create unique this intent from other intent using setData */
intent.setData(Uri.parse("http://www.google.com"));
/*create new task for each notification with pending intent so we set Intent.FLAG_ACTIVITY_NEW_TASK */
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
Log.d(TAG, "Preparing to send notification...: " + msg);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.hcp)
.setContentTitle("GCM Notification")
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setSmallIcon(smalIcon)
.setTicker(notificationTitle)
.setLargeIcon(largeIcon)
.setContentText(notificationContent)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentIntent(pendingIntent);
;
Notification notification=mBuilder.build();
mBuilder.setContentIntent(pendingIntent);
mNotificationManager.notify((int) when, notification);
Log.d(TAG, "Notification sent successfully.");
}
Assuming that the data (msg) your receiving is from a web service. Now along with the msg parameter, you must be getting some other parameters by which you can distinguish that the following notification is Audio/Video call or message.
So you can create a method that will return the class name which can be used instead of NotificationDetailsActivity.class
private Class<?> getClassFromType(String type) {
if(type.equals("Audio")
return AudioActivity.class;
else if(type.equals("Video")
return VideoActivity.class;
else if(type.equals("Message")
return MessageActivity.class;
}
The final code will be something like this:
Intent intent =new Intent(getApplicationContext(), getClassFromType(type));
Here type will be the variable that distinguishes the notification.
Hope this will solve your problem.
I am working on PUSH Notification.I am using the following code while receiving messages form GCM :
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
/**
* 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().
*/
// [START receive_message]
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.e(TAG, "From: " + from);
Log.e(TAG, "Message: " + message);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream message.
}
// [START_EXCLUDE]
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
// [END_EXCLUDE]
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* #param message GCM message received.
*/
private void sendNotification(String message) {
Intent intent = new Intent(this, WelcomeActivity.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);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
//.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle("GCM Message")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());
}
}
Message is received but is not displayed as notification.I don't know what i am missing here .Please help me to fix the issue .
Log:
03-07 16:50:21.617 32412-32678/com.almabay.almachat E/MyGcmListenerService﹕ From: 20130254292
03-07 16:50:21.618 32412-32678/com.almabay.almachat E/MyGcmListenerService﹕ Message: Hi Deepak this is is notification from GCM server. 07.03.2016 16:20:52
public void notify (int id, Notification notification)
Post a notification to be shown in the status bar. If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.
http://developer.android.com/reference/android/app/NotificationManager.html#notify%28int,%20android.app.Notification%29
public void showNotificationMessage(String title, String message, Intent intent) {
if (TextUtils.isEmpty(message))
return;
int icon = R.drawable.ic_launcher;
int mNotificationId = new Random().nextInt(5000);
PendingIntent resultPendingIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext);
Notification notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setStyle(inboxStyle)
.setContentIntent(resultPendingIntent)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
// .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(mNotificationId, notification);
}
Hope this will give idea to understand how notification works in android.