I need to embed a newline in a notification. I have two lines of data that are different and I need to embed a newline to distinguish between the two.
I trued a backslash-n, but that does not work.
Is there a way to do this?
You do not need to use RemoteViews or a custom layout to show multiple lines, despite what others have said here!
Multiline texts are possible, but only when the notification is expanded.
To do this, you can use NotificationCompat.BigTextStyle. And if you read the dev guides here then you'll notice that they mention this tip:
Tip: To add formatting in your text (bold, italic, line breaks, and so on), you can add styling with HTML markup.
So, in other words:
val title = "My Title"
val body = "Line 1<br>Line 2<br><i>Italic Line 3</i>"
val formattedBody = SpannableString(
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) Html.fromHtml(body)
else Html.fromHtml(body, Html.FROM_HTML_MODE_LEGACY)
)
NotificationCompat.Builder(context, channelId)
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
.setContentTitle(title)
.setContentText(formattedBody)
.setStyle(NotificationCompat.BigTextStyle().bigText(formattedBody).setBigContentTitle(title))
.setSmallIcon(R.drawable.ic_small_notification_icon)
.build()
Things to note about how this works:
The title can have no formatting (i.e. don't try to use HTML here)
The body can have as much formatting as we want, but we must note that the line breaks won’t display when the notification is collapsed. All other HTML formatting works fine in both collapsed/expanded states. You can bold, italicize, etc. as much as you want (I think)
If you don't want to send HTML formatting in your push notification, then another option is to use markdown formatting of some sort and manually handle this before your notification building by using SpannableStringBuilder
As far as I know there is no way to do this other than creating a custom Notification layout. The Notification documentation has a step-by-step process on doing this and is quite thorough. Here is the link to that.
Creating the two lines as you require would just mean putting in an extra TextView in the layout XML. Then you would just set each TextView's text to your two lines of data, as the example shows.
You need to make custom notification builder in your app. more detail here : https://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView, It takes me so long to find out the way to make firebase to call onMessageReceived in all cases.
app in foreground
app in background
app was killed.
basically your message to firebase via api must not have "notification" key in your json request to firebase server and only use "data" key as show below, firebase service will call your onMessageReceived in all cases listed above.
{
"to": "/topics/your_topic",
"data": {
"key1":"data_key1",
"title":"",
"line1":"data1",
"line2":"data2"
}
}
Related
I have a few notifications running on my app built with NotificationCompat
Depending on the type, they show background bitmaps, or list of text, also most of them have 1 or 2 actions using the code:
builder.addAction(R.drawable.ic_notification, text, pendingIntent)
some of those actions makes sense for a watch (for example: "like" or "reply") and some doesn't (for example: "view album").
I thought I could use the setLocalOnly(boolean) method for it, but I found out that it is applied to the whole notification, not just to individual actions.
I've also been checking on NotificationCompat.Action and NotificationCompat.Action.WearableExtender but couldn't find anything that would be relevant.
So the question:
is there a way to make the notification show on the watch, but only with some of the actions but not others?
Please see docs in the paragraph "Specify wearable-only actions".
The XMPP message being sent has some custom attribtes added in message tag like :
<message to = " asdf" from = "asdf" type = "chat" id="adsf" direction = "asdf" speed = "asdf">
<body>Speed</body>
</message>
Message that is being sent is all fine. But on receiving end , I dnt know how to read these extra attributes i.e. direction and speed added in message tag. I tried to make custom PacketListener but for that i need to change the whole smack library bcz every class is connected to other class.
You can't.
Never add custom values to specified stream element attributes (e.g. a new value for the type attribute of messages), and never add new attributes to top level elements (like you did with msgType, msgTimeStamp and so on).
This has the potential to break things! Don't do it. See also "XEP-0134: XMPP Design Guidelines § 2.1 XMPP is Sacred". That's why it's not possible in Smack. Instead, use a custom extension element, like xnyhps showed in his example (the data element). See also "RFC 6120 § 8.4 Extended Content" Those are called PacketExtension's in Smack.
See also this answer and question.
I've implemented a notification listener to look out for a Gmail notification.
I want to collect the expanded text (bigtext) from the notification as shown in the notification below:
See "----Forwarded message---", etc. which only appears when the user expands the notification to show the action buttons.
This string value does not appear in the notification's "EXTRAS" data...
http://developer.android.com/reference/android/app/Notification.html
After viewing the above link, I further investigate the bundle (EXTRAS) data. When you debug it and look at the variable, you can find that all information regards the notification are stored in the bundle and you can get the detail by
notifyBundle.extras.getCharSequence("android.textLines") for multi line notification and
notifyBundle.extras.getString("android.text") for single line notification.
For more information, look at the variable in eclipse debugging mode
Image of variables in bundle for single line notification
Image of variables in bundle for multi line notification
Note: The extra bundle only available in API19 (Kitkat). I've never tried in device which lower than API19.
I ran into a similar problem with Gmail running on Android 7.
Eventually, I've realized (with some help from another thread) that he solution was different from the existing answers here - what you're looking for can be accessed in a different way:
Bundle extras = statusBarNotification.getNotification().extras;
extras.get(Notification.EXTRA_BIG_TEXT) == null ? null : extras.get(Notification.EXTRA_BIG_TEXT).toString();
This way you will always get either a String or null, even if the value you're looking for isn't originally a string. This is done because calling getString(Notification.EXTRA_BIG_TEXT) directly would return null instead, at least in some cases.
If there are any other values you're not sure where they might be stored, you can try iterating through the entire extras bundle, as explained here.
Finally, I am able to solve this issue by using this code.
ArrayList<StatusBarNotification> groupedNotifications = new ArrayList<>();
for(StatusBarNotification statusBarNotification : mNotificationManager.getActiveNotifications()) {
if(statusBarNotification.getNotification().getGroup().equals(NOTIFICATION_GROUP)) {
groupedNotifications.add(statusBarNotification);
}
}
CharSequence stackNotificationMultiLineText[] = groupedNotifications.get(ZEROTH_INDEX).getNotification().extras.getCharSequenceArray(NotificationCompat.EXTRA_TEXT_LINES);
If you try to use getCharSequence("android.textLines"), it returns you null because NotificationCompat.EXTRA_TEXT_LINES returns you the array of CharSequence and not a single CharSequence object.
I found a shorter way of accessing the expanded notification. This works in API 24.
If you are getting null while accessing getCharSequence("android.textLines"), this is because it actually returns an array of CharSequence as rightly pointed out by Puneet above.
So rather access them like this:
if (extras.getCharSequenceArray("android.textLines") != null)
text = Arrays.toString(extras.getCharSequenceArray("android.textLines"));
I am writing NotificationListenerService ,
where I want to get the details of notification sent to status bar.
But only thing we get is Ticket text , which is null in some cases.
Correct, ticker text is not a required field when building a notification. In fact, the only required notification contents are:
A small icon - returned by icon
A title - returned by extras.getCharSequence(Notification.EXTRA_TITLE)
Detail text - returned by extras.getCharSequence(Notification.EXTRA_TEXT)
Unfortunately, the extras bundle is only available on Android 4.4 (KitKat) devices - previous versions do not have any easy access to this data - you only have access to the RemoteViews which you'd need to inflate and parse manually (definitely not recommended).
Ticker text is optional, and may be null in some cases.
You haven't posted any code, but are you using the onNotificationPosted(StatusBarNotification) method from NotificationListenerService? That was implemented in API 18 (Android 4.3), so it should work for you. The documentation states that the full Notification object should be returned, which should give you more than just the ticker text.
my app searches for new articles and sends a notification like "5 new articles". However when i send another one, i want to have it update the text to lets say there were 3 new so something like "8 new articles" BUT "3 new articles" if the user has dismissed that previous notification. I hope you get it.
Is there a way to know that notification was dismissed so i can reset the count?
Thanks !
This is a rather belated answer but I was looking to find out how to do this myself so perhaps it'll be useful to others. In API level 18 the following service was introduced which should make this straightfoward as you can now get a callback whenever a notification is added or removed:
https://developer.android.com/reference/android/service/notification/NotificationListenerService.html
In particular for the original question see the onNotificationRemoved method
The other option mentioned by jpop above is to use the builder's setDeleteIntent method when creating the notification, which will give a callback when the notification is deleted. This would then require you to maintain the state of the existing raised notifications somewhere else as it only tells you when something is added, not removed.
If your app has a database you can do this: Create a table that has some fields like id as int, article name as string, and isdismissed as boolean. So, each time you want to send a notification, you should count the records that the isdismissed field equals false.
In the other hand, each time user select a notification, the related isdismissed field must be equal true.
In addition, this sample from developer.android.com maybe can help you:
http://developer.android.com/guide/topics/ui/notifiers/notifications.html
the listener don't work since android Nougat, a new access rule have been added
on android device : parameters -> applications -> gear menu -> spécial access -> notifications access
use : catch on swipe to dismiss event