I have made a chat app in firebase and users are being notified when a new message comes by the below codes.
private void sendNotification(String title, String message, String receiver, String receiverUid, String firebaseToken) {
Intent intent = new Intent(this, ChatActivity.class);
intent.putExtra("name",title);
intent.putExtra(Const.ARG_RECEIVER, receiver);
intent.putExtra(Const.ARG_RECEIVER_UID, receiverUid);
intent.putExtra(Const.ARG_FIREBASE_TOKEN, firebaseToken);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
char[] ch = firebaseToken.substring(0,3).toCharArray();
String a = "";
for (char aCh : ch) {
a = a + Integer.toHexString(aCh);
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, Integer.parseInt(a), intent,
PendingIntent.FLAG_ONE_SHOT);
// Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_noti)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
// .setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Integer.parseInt(a), notificationBuilder.build());
}
I want to receive different notification when a different user sends a message but for the same user, the notification should be updated. I tried to set unique id by taking the Unicode of first 3 letters of Firebase token of the user but then also it is showing only one notification. If I chat with 2 people the user with whom I have started chat first shows notification but not the second one.
Please have a look and help. Thanks
Just change FLAG_ONE_SHOT to FLAG_UPDATE_CURRENT.
FLAG_ONE_SHOT :
Flag indicating that this PendingIntent can be used only once.
FLAG_UPDATE_CURRENT :
Flag indicating that if the described PendingIntent already exists, then keep it but replace its extra data with what is in this new Intent.
Related
I am trying to get push notifications using FCM in my android application the code is working fine when notification is sent from FCM console it works fine both in foreground and background, but when I send notifications using curl through FCM I am getting data which is visible in logcat but notification is displayed only when application is in background and does not show up when application is in foreground. onMessageReceived is called every time when data is pushed from FCM but notification is not visible when application is in foreground.
private void sendNotification(String body , Map<String,String> data) {
int finalSecId = Integer.parseInt((String) data.get("sec_id"));
int sec = Integer.parseInt((String) data.get("sec"));
String extra1 = (String) data.get("extra1");
String extra2 = (String) data.get("extra2");
Intent intent = new Intent(this,HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0/*Request code*/, intent, PendingIntent.FLAG_ONE_SHOT);
//Set sound of notification
Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notifiBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.login_meter)
.setContentTitle(getString(R.string.app_name))
.setContentText(body)
.setAutoCancel(true)
.setSound(notificationSound)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /*ID of notification*/, notifiBuilder.build());
}
I have currently setup a small application which sets an alarm on the device and stores relevant information inside of an SQL database e.g. Alarm name and time. When the alarm is activated my application sends a notification to the user. Currently each notification is static which means every message is the same. I would like to now allow my application to grab the name of the alarm which has been activated and display it in the notification. Now I know that when setting multiple alarms you require multiple ID's which I have stored in side of my SQL and I'm guess the same when it comes to sending a notification. Is there a way of matching my Alarms ID with one on a notification so that it knows what message to send e.g. alarm name?
Current code for setting my Alarm
pendingIntent = PendingIntent.getBroadcast(view.getContext(), Integer.valueOf(alarm_request_code), receiver, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, myCalendar.getTimeInMillis(), pendingIntent);
intentArrayList.add(pendingIntent);
My Broadcast receiver...
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Intent moveActivity = new Intent(context, AlarmActivity.class);
moveActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, moveActivity, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setContentTitle("Standard text")
.setContentText("Standard text")
.setSmallIcon(R.mipmap.ic_launcher)
.setAutoCancel(true);
notificationManager.notify(0, builder.build());
}
//////////////
Update on my situation which is slowly driving me crazy
I can now set the text from my SQL to my notification but its only the first from my database each time. Now I've come up with two possible solutions which are only theory's.
Is there a way in which each time the database is called to the notification it will move onto the next result?
As I mentioned above I'm setting an alarm and when the alarm goes off it then calls the notification. Now In my pending intent for the alarm I'm giving it a id which you can see as alarm_request_code is there a way of giving it to my notification ID and then setting up a statement where if the notification ID is equal to or in the list of my alarm ID's stored on my SQL then it will search for the correct text to input.
MyDatabaseHandler myDatabaseHandler = new MyDatabaseHandler(context, null, null, 1);
Cursor cursor = myDatabaseHandler.getAllProducts();
// Information we are trying to acquire but can only get first result
String name = cursor.getString(cursor.getColumnIndexOrThrow("alarm_name"));
String date = cursor.getString(cursor.getColumnIndexOrThrow("alarm_date"));
// Alarm ID FROM SQL which we want to match with the NOTIFICATION ID.....
String alarm_request_code = cursor.getString(cursor.getColumnIndexOrThrow("alarm_code"));
////
Log.i("The reciever is working", "perfect");
//create an intent to service
Intent service_Intent = new Intent(context, MessageService.class);
context.startService(service_Intent);
//Notification
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Intent moveActivity = new Intent(context, AlarmActivity.class);
moveActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Works with moveActivity to move the user back to main application.
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, moveActivity, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setContentTitle(name)
.setContentText(date)
.setSmallIcon(R.mipmap.ic_launcher)
.setAutoCancel(true);
notificationManager.notify(Integer.valueOf(alarm_request_code), builder.build());
}
}
To update text store mBuilder variable
and update later in this way:
mBuilder.setContentTitle(head);
mBuilder.setContentText(body);
mNotificationManager.notify(SIMPLE_ID, mBuilder.build());
EDIT
private void simple() {
Intent intent = new Intent(context, AlarmActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle(getResources().getString(R.string.app_name))
.setContentText(getResources().getString(R.string.app_name))
.setContentIntent(pIntent);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
mBuilder.setSmallIcon(R.drawable.ic_done_24dp);
} else {
mBuilder.setSmallIcon(someiconLollipop);
mBuilder.setColor(somecolorLollipop]);
}
noti = mBuilder.build();
//use flags if you need:
noti.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
mNotificationManager.notify(SIMPLE_ID, mBuilder.build());
}
to update the text:
private void showText() {
String head = yournewhead;
String body = yournewbody;
mBuilder.setContentTitle(head);
mBuilder.setContentText(body);
mNotificationManager.notify(SIMPLE_ID, mBuilder.build());
}
Per the docs you can do the following:
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
// Because the ID remains unchanged, the existing notification is
// updated.
mNotificationManager.notify(
notifyID,
mNotifyBuilder.build());
The trick here is your notify id, which must be the same in order to behave appropriately, in your case 0.
So as long it has not been dismissed it should work accordingly. I will suggest having a unique id as a constant for your custom notification such as 123.
notificationManager.notify(0, builder.build());
Bug is present on phones with screen pin/graphical key lock. Without it works just fine.
When user taps on push notification in starts main activity and thats all, if there is no pin or graphical key it starts needed activity.
This is my GCM listener code:
#Override
public void onMessageReceived(String from, Bundle data) {
String id = data.getString("news_id");
String message = data.getString("message");
Random random = new Random();
Intent intent = new Intent(this, SpecificNewsActivity.class);
intent.putExtra("newsId", id);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, random.nextInt(), 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(getString(R.string.app_name))
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(random.nextInt(), notificationBuilder.build());
}
Any ideas how to fix this ?
Edit: Looks like this problem is present only on Chinese phones (Meizu, Xiaomi).
If anyone else face this. The question was solved simply - requests to the server was moved from Activity which has fragment container to the fragment itself. Without this on Xiaomi and Meizu activity stopped on the stage of fragment transaction in the frame layout.
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 using GCM Notification in my app.I parse the data in "onMessageReceived" method where i get some unique "URL" corresponding to GCM Message.When I receive single notification Every thing is fine,But when i receive multiple notifications problem occurs when i tap any notification last received notification url loads.
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
String country = data.getString("country");
String url = data.getString("url");
String description = data.getString("description");
String id = data.getString("id");
}
I get url from GCM Notification
Intent intent = new Intent(this, Detailview.class).putExtra("url", url);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(Mainscreen.class);
stackBuilder.addNextIntent(intent);
PendingIntent pendingIntent= stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_ONE_SHOT );
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
contentView.setImageViewResource(R.id.image, R.drawable.ic_stat_ic_notification);
contentView.setTextViewText(R.id.title, message);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setAutoCancel(true)
.setContent(contentView)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Integer.parseInt(id)
/*ID of notification */
, notificationBuilder.build());
so when i tap the notification i am able to launch only last url How i can solve this problem?
use
PendingIntent.FLAG_UPDATE_CURRENT
when creating PendingIntent.
Also before passing intent to PendingIntent set its action different everytime. e.g.:-
intent.setAction(Long.toString(System.currentTimeMillis()));
Just add time of arrive as a differntiator to each notification
PendingIntent pendingIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);