So I have an app that receives the temperature via MQTT. To avoid getting spammed by notifcations, I want the app to notify once, that is vibrate, play sound and then the next three times (if the notification isn't dismissed) it will only update the temperature value. So:
Notify
Update temp
Update temp
Update temp
5(or 1 if you will) Notify
This is my code:
private final NotificationCompat.Builder builder = new NotificationCompat.Builder(this, id);
private void handleNotification(String message, String topic) {
if (notifManager == null) {
notifManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
if (isNotifRunning() && ticker < 3) {
updateNotif(message);
ticker++;
} else {
createNotif(message);
ticker = 0;
}
}
private void createNotif(String message) {
Intent intent;
PendingIntent pendingIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = notifManager.getNotificationChannel(id);
if (mChannel == null) {
mChannel = new NotificationChannel(id, name, importance);
mChannel.setDescription(description);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200});
notifManager.createNotificationChannel(mChannel);
}
intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentTitle(getString(R.string.notifTmpLowTitle))
.setSmallIcon(R.drawable.ic_ac_unit_black_24px)
.setContentText(getString(R.string.notifTmpLowText) + " " + message + Constants.CELSIUS)
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setTicker(message)
.setColor(getResources().getColor(R.color.colorCold))
.setVibrate(new long[]{100, 200});
} else {
intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentTitle(getString(R.string.notifTmpLowTitle))
.setSmallIcon(R.drawable.ic_ac_unit_black_24px)
.setContentText(getString(R.string.notifTmpLowText) + " " + message + Constants.CELSIUS)
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setTicker(message)
.setVibrate(new long[]{100, 200})
.setColor(getResources().getColor(R.color.colorCold))
.setPriority(Notification.PRIORITY_HIGH);
}
Notification notification = builder.build();
notifManager.notify(NOTIFY_ID, notification);
}
//TODO Doesn't update, posts a new notification.
private void updateNotif(String message) {
builder.setContentText(getString(R.string.notifTmpLowText) + " " + message + Constants.CELSIUS);
Notification notification = builder.build();
notification.flags = Notification.FLAG_ONGOING_EVENT;
notifManager.notify(NOTIFY_ID, notification);
}
//---------------------------------------------
With this code, I always get, what it looks like, a brand new notification with sound and vibration. I've looked at previous questions regarding this and they all say that it's important to use the same builder and as you can see, I have done this. Is there some change in newer Android versions that I'm not aware of? I've tested on both 7.1.1 and 8.1.
You'll want to call setOnlyAlertOnce(true) to cause updates to your notification to not send sound/vibration.
Related
Be informed, we are trying to send notification with a button using Addaction. The button Start has a intent that directly opens a url in a webview, which works perfectly fine with code given below
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("uri", uri);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//int notification_id = nid!=null ? Integer.parseInt(nid) : MainActivity.ASWV_FCM_ID;
int m = (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE);
int notification_id=m;
Intent buttonIntent = new Intent(this, ButtonReceiver.class);
buttonIntent.putExtra("notificationId",notification_id);
//Create the PendingIntent
PendingIntent btPendingIntent = PendingIntent.getBroadcast(this, 0, buttonIntent,0);
String channelId = MainActivity.asw_fcm_channel;
Uri soundUri=Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName() + "/raw/pristine");
NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.mipmap.ic_launcher, tag, pendingIntent).build();
NotificationCompat.Action action1 = new NotificationCompat.Action.Builder(R.mipmap.ic_launcher, "Dismiss", btPendingIntent).build();
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder1 = new NotificationCompat.Builder(this, MainActivity.asw_fcm_channel)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(message)
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setAutoCancel(false)
.addAction(action)
.addAction(action1)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(channelId, "My Notifications", NotificationManager.IMPORTANCE_HIGH);
AudioAttributes attributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
// Configure the notification channel.
mChannel.setDescription("Common notifications");
mChannel.enableLights(true);
mChannel.setLightColor(Color.RED);
mChannel.setSound(soundUri, attributes);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
mChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
notificationManager.createNotificationChannel(mChannel);
}
Notification noti = notificationBuilder1.build();
noti.flags = Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(notification_id, notificationBuilder1.build());
Update:
I'm sorry but i'm not actually a expert or a regular coder in android java, so you gotta help me here a little bit more. I have passed on my notification id down in the code, but the problem here is how do i invoke removeNotification in the pendingIntent which also carries my url to where the link will go onclick
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("uri", uri);
intent.putExtra("notificationId",notification_id);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
public static void removeNotification(int notification_id) {
try {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(notification_id);
}
} catch (Exception e) {
}
}
But we also like the notification to be dismissed simultaneously onclick. We tried using .setAutocancel (true) and notification flags like FlAG_AUTO_CANCEL, but the button just does first action right of going into webview url and not cancelling the notification.
Shall appreciate should you help us out.
Send the notification id in the intent to activity and use the code to cancel.
public static void removeNotification(Context context, int notification_id) {
try {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(notification_id);
}
} catch (Exception e) {
Timber.d(e);
}
}
Intent intent = getIntent();
if (intent.hasExtra("notificationID")) {
removeNotification(context, intent.getIntExtra("notificationID", 0));
}
There is a Reminder application. Now users created 5 Reminders. R1, R2, R3, R4, R5.
And for all reminders time is same. So all reminders came in same time. Now I tap on notification which is R1. and when I tap, it opens a particular activity and show according to details because I sent Id of that reminder in intent.
Now I click on R2/R3/R4/R5, it is opening details according to R1 only instead of R2/R3/R4/R5.
Note: In onReceive, I create notification from that. Also, for all reminders, I open same activity, but details on that activity should be different according to Reminder ID. Also, when I send ReminderId/mReceivedId in intent, it is correct, not the same.
Code:
editIntent = new Intent(context, ReminderDetailActivity.class);
editIntent.putExtra(REMINDER_ID, mReceivedId);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
pendingIntent = PendingIntent.getActivity(context, rowId, editIntent, 0);
Complete code (I call createNotification() from onReceive):
private void createNotification() {
int rowId = getRowId(mReceivedId);
Uri mUri;
if (preferenceManager.getRingtoneUri() != null) {
mUri = Uri.parse(preferenceManager.getRingtoneUri());
} else {
mUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
String mTitle = reminder.getTitle();
String id = "1";
PendingIntent pendingIntent;
NotificationCompat.Builder builder;
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
Intent editIntent;
if (SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
assert mNotificationManager != null;
NotificationChannel mChannel = mNotificationManager.getNotificationChannel(id);
if (mChannel == null) {
mChannel = new NotificationChannel(id, mTitle, importance);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
mNotificationManager.createNotificationChannel(mChannel);
}
builder = new NotificationCompat.Builder(context, id);
editIntent = new Intent(context, ReminderDetailActivity.class);
editIntent.putExtra(REMINDER_ID, mReceivedId);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
pendingIntent = PendingIntent.getActivity(context, rowId, editIntent, 0);
builder.setContentTitle(mTitle)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setContentTitle(mTitle)
.setSmallIcon(R.drawable.ic_alarm_black_24dp)
.setSound(mUri)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Have you completed your task?"))
.setBadgeIconType(NotificationCompat.BADGE_ICON_LARGE)
.addAction(R.drawable.ic_icon_alarm, context.getString(R.string.pay_now), pendingIntent);
builder.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
} else {
builder = new NotificationCompat.Builder(context, id);
editIntent = new Intent(context, ReminderDetailActivity.class);
editIntent.putExtra(REMINDER_ID, mReceivedId);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
editIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
pendingIntent = PendingIntent.getActivity(context, rowId, editIntent, 0);
builder.setContentTitle(mTitle)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setContentTitle(mTitle)
.setSmallIcon(R.drawable.ic_alarm_black_24dp)
.setSound(mUri)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_icon_alarm, context.getString(R.string.pay_now), pendingIntent)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Have you completed your task?"))
.setBadgeIconType(NotificationCompat.BADGE_ICON_LARGE)
.setPriority(Notification.PRIORITY_HIGH);
builder.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
}
Notification notification = builder.build();
mNotificationManager.notify(rowId, notification);
}
Welcome to code party 🎉
As i seen, u want start an activity when another is already opened and it can’t get other extras.
So you must before sending another intent, clear bundle or finish activity.
Edited:
use this in your activity
#Override
protected void onNewIntent(final Intent intent) {
super.onNewIntent(intent);
this.setIntent(intent); //just add this line when overrided
}
do it and update me
I am making MQTT client app using paho MQTT client dependency.
Implementing code in a Background Service. and everything works well except the Notification isn't working!
Service code snippet is here:
My Codes occurs inside the TimeDisplayTimerTask inner-class.
This code located at the callback function :
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
mIntent = new Intent(getApplicationContext(), MainActivity.class);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, mIntent, 0);
createNotificationChannel();
Toast.makeText(getApplicationContext(),"A message received : "+ new String(message.getPayload()),Toast.LENGTH_SHORT).show();
vibrator.vibrate(500);
myRingtone.play();
mBuilder .setContentTitle("Message received at : " + mTopic)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setContentText("Message : "+ new String(message.getPayload()));
mNotificationManager.notify(0, mBuilder.build());
}
And this code creates a notification channel (as Google developers guide mentioned to write):
Posted with help of this answer.
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String chanel_id = "3000";
CharSequence name = "Mqtt message";
String description = "Message arrived";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel mChannel = new NotificationChannel(chanel_id, name, importance);
mChannel.setDescription(description);
mChannel.enableLights(true);
mChannel.setLightColor(Color.BLUE);
mNotificationManager = getSystemService(NotificationManager.class);
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(mChannel);
}
mBuilder = new NotificationCompat.Builder(getApplicationContext(), chanel_id);
}
else
{
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(getApplicationContext());
}
}
When it receives a message, A toast message appears holding the message.
But it doesn't push notification.
Checked Apps and Notifications, All notifications are allowed.
SOLVED :
the setter method .setSmallIcon must be called to successfully build a notification.
Which was not important to me.
I am implementing firebase push notification in my app, the app is showing the push notification also. But my problem is - I may send different types of push notifications based on different topics.
Ex -
1. If I am sending a push notification on App Update, then on clicking that notification by the user, he should be redirected to PlayStore
If I am sending a push notification on New Contents, then on clicking that notification by the user, he should be redirected to App's MainActivity
If I am sending a push notification on New Contest, then on clicking that notification by the user, he should be redirected to App's ContestActivity
I implemented it using the below code in "MessageReceiver" class as --
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String title = remoteMessage.getNotification().getTitle();
String message = remoteMessage.getNotification().getBody();
showNotifications(title, message);
}
private void showNotifications(String title, String msg) {
Intent i = null;
if(title.equals("DoUp Now - Update")){
Uri uri = Uri.parse("https://play.google.com/store/apps/details?id=com.s2s.doupnow"); // missing 'http://' will cause crashed
i = new Intent(Intent.ACTION_VIEW, uri);
}
else if(title.equals("DoUp Now - New Content")){
i = new Intent(this, MainActivity.class);
}
else if(title.equals("DoUp Now - New Notification")){
i = new Intent(this, NotificationActivity.class);
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, REQUEST_CODE,
i, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder, mBuilderOld;
final int NOTIFICATION_ID = 1;
final String NOTIFICATION_CHANNEL_ID = "my_notification_channel";
mNotifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);
// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
mNotifyManager.createNotificationChannel(notificationChannel);
mBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
mBuilder.setContentTitle(title)
.setContentText(msg)
.setSmallIcon(R.drawable.doupnowlogo)
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
}
else
{
mBuilderOld = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
mBuilderOld.setContentTitle(title)
.setContentText(msg)
.setSmallIcon(R.drawable.doupnowlogo)
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(NotificationManager.IMPORTANCE_MAX);
mNotifyManager.notify(NOTIFICATION_ID, mBuilderOld.build());
}
}
But on clicking any notification by the user, he is always redirected to App's MainActivity only.
Can anyone guide me where i am missing.
If you are comparing title using api the you have to check the title using JSON object like this.
JSONObject data = json.getJSONObject("data");
String title = data.getString("title");
String message = data.getString("message");
Make sure the title you get is equal as title you are comparing and add flags in intent.
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
I am generating local notification with multiple lines. All lines are showing properly but contentTitle and contentText are not showing.
Here is my code to generate a notification:
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(notificationIntent);
int num = (int) System.currentTimeMillis();
PendingIntent pendingIntent = stackBuilder.getPendingIntent(num, PendingIntent.FLAG_UPDATE_CURRENT);
String id = "notification_channel_id";
CharSequence name = "Message_Notification";
Bitmap bm = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, id)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("title")
.setContentText("time")
.setAutoCancel(true)
.setGroupSummary(true)
.setGroup(GROUP_KEY)
.setContentIntent(pendingIntent)
.setChannelId(id);
if (subTitle != null) {
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.setBigContentTitle("Dose Reminder");
if (subTitle.contains("---")) {
String[] splitStrings = subTitle.split("---");
for (int i = 0; i < splitStrings.length; i++) {
inboxStyle.addLine(splitStrings[i]);
}
} else {
inboxStyle.addLine(subTitle);
// Moves the expanded layout object into the notification object.
notificationBuilder.setStyle(inboxStyle);
}
// Moves the expanded layout object into the notification object.
notificationBuilder.setStyle(inboxStyle);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notificationBuilder.setColor(ContextCompat.getColor(context, R.color.colorAccent));
} else {
notificationBuilder.setLargeIcon(bm);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
// The user.-visible description of the channel.
String description = "Notifications contains messages which was sent by dev team.";
int importance = NotificationManager.IMPORTANCE_MAX;
NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_DEFAULT);
// Configure the notification channel.
mChannel.setDescription(description);
mChannel.enableLights(true);
// Sets the notification light color for notifications posted to this
// channel, if the device supports this feature.
mChannel.setLightColor(Color.RED);
if (notificationManager != null) {
notificationManager.createNotificationChannel(mChannel);
}
}
// Sets an ID for the notification
// Gets an instance of the NotificationManager service
final NotificationManager mNotifyMgr =
(NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
// Builds the notification and issues it.
if (mNotifyMgr != null) {
mNotifyMgr.notify(num, notificationBuilder.build());
}
When notification comes "title" and "time" are not showing. It showing "Dose Reminder" and subTitles in multiple lines.
Am I missing something?
setBigContentTitle(CharSequence title)
Overrides ContentTitle in the big form of the template.
https://developer.android.com/reference/android/app/Notification.InboxStyle
Check Use MessagingStyle section
https://developer.android.com/training/notify-user/build-notification
JFYI by default timestamp is gone in push notifications, Android 7 (Nougat) onwards