Android NotificationCompat.Builder works with three buttons but not four - java

I have a notification which includes buttons to control a media player. As implemented below, everything works fine.
Notification notification = builder
.setContentText(contentText)
.setSmallIcon(icon)
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingIntent)
.setContentTitle(
getResources().getString(R.string.notification_title))
.addAction(R.drawable.ic_action_previous, "", previousPendingIntent)
// Adding this causes uglyness
// .addAction(R.drawable.ic_action_rewind20, "", jumpBackPendingIntent)
.addAction(playPauseIcon, "", playPausePendingIntent)
.addAction(R.drawable.ic_action_next, "", nextPendingIntent)
.build();
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(uniqueid, notification);
However, when I comment out the line
.addAction(R.drawable.ic_action_rewind20, "", jumpBackPendingIntent)
The third buttons gets kicked out.
The Android documentation on this is pretty sparse. Nothing in the addAction docs implies that there's a limit.
Clearly all of the buttons could fit in the notification. What am I missing?
Full Source Code

Update adneal's link to the latest code here as an answer:
A notification in its expanded form can display up to 3 actions, from
left to right in the order they were added.

Related

How to change app notification badge count programmatically without sending notification (java/android)

I want to change the notification badge count every time a user arrives at the home page (or presses a button for testing purposes). The only way I can do that right now is by sending a notification like so:
Notification notification = new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setContentTitle("New Messages")
.setContentText("You've received 3 new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setNumber(messageCount)
.build();
However, I want to change the badge count without sending a notification as I don't want to clutter up the notification panel.
Welcome to StackOverflow.
It would appear the pacakge you're using is no longer maintained, as it's been deprecated in favour of AndroidX and I'd recommend migrating to that if it's an option for your project.
If I'm correct in my assumption, you're attempting to do something similar to what you can achieve on iOS, however the Android SDK does not support this out of the box, although there appears to be a workaround
As such, the function you're calling cannot be used for that particular purpose. The setNumber function sets the number displayed in the long press menu
All this having been said
You CAN update a notification that's already been sent, and update the number shown in the long press menu using the setNumber method, as detailed in this article
TL;DR:
Post the notification with an identifier using the following method and save the identifier somewhere for later: NotificationManagerCompat.notify(notificationId, builder.build());
Rerun the same code you posted in your question, updating the badge number in the process
Run NotificationManagerCompat.notify() again, passing the SAME notification id and the NEW notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
int notificationID = 123456;
int messageCount = 1;
Notification notification = new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setContentTitle("New Messages")
.setContentText("You've received 3 new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setNumber(messageCount)
.build();
notificationManager.notify(notificationID, notification);
//Now update the message count
messageCount++;
Notification notification = new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setContentTitle("New Messages")
.setContentText("You've received 3 new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setNumber(messageCount)
.build();
notificationManager.notify(notificationID, notification);

Oreo & Pie Notifications

Problem: My app needs notifications that can be customized by the user. eg. set different sounds, titles, texts for notifications
Issue: I'm aware notification channels are set only once and cannot be modified so I thought I could just use variables however even with variables once I have picked a sound it stays as that sound and cannot be changed at all. The only solution I can think is a new channel each time something is changed which just seems silly.
Surely there is another way??
Also to add to all of this, on Android Pie the notification sound does not work at all I can't work out why.
Uri soundUri = Uri.parse(notificationSound);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "CH_ID")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(customTextTitle)
.setContentText(customTextBody)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if(soundUri != null){
// Changing Default mode of notification
notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
// Creating an Audio Attribute
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build();
// Creating Channel
NotificationChannel notificationChannel = new NotificationChannel("CH_ID","Testing_Audio",NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setSound(soundUri,audioAttributes);
mNotificationManager.createNotificationChannel(notificationChannel);
}
}
mNotificationManager.notify(0, notificationBuilder.build());
}
I have solved the problem albeit in a hacky way :( I have ended up setting the sound to null if >=Oreo and using a media player to play the notification sound also setting the audioStream to STREAM_NOTIFICATION. Obviously not ideal but as it's a notification and not an alarm the audio shouldn't go over the time set to perform task during onReceive.
The only problem I can see with this solution is if the user decides to mute the notification/make adjustments to the channel on their phone. Muting the sound there obviously will have no effect to the sound played by media player and will most likely show as no sound anyway which is unfortunate.
try {
mp.setDataSource(context.getApplicationContext(), soundUri);
mp.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mp.prepare();
mp.start();
} catch (Exception e) {
//exception caught in the end zone
}
For anyone else having this issue I found a really great post here which is the same solution as mine but more robust and in more depth. Android O - Notification Channels - Change Vibration Pattern or Sound Type
you have wrong implemented, set sound like below
notificationBuilder.setSound(soundUri,audioAttributes);

Firebase Cloud Messaging Notification only shows when I open the "notification tab"

So I got push-notifications working with Google's Firebase Cloud Messaging. The only problem now is that the notification doesn't show any alert, only if I pull down the notification drawer that I see it's there.
I've got this part of the code where I think that "popup" feature is added
public void displayNotification(String title, String body){
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext, Constants.CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(body);
Intent intent = new Intent(mContext, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext,0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pendingIntent);
NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if(mNotificationManager != null) {
mNotificationManager.notify(1, mBuilder.build());
}
}
Other problem I have is that when I click the notification, it opens the activity but doesn't delete the notification.
Foreground pop-up
Under the builder, you are required to set high or max priority as well as the default notification vibration / sound so that you can see the 'pop-up' window
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL);
Background pop-up
To achieve background pop-up, you need to fine-tune your FCM payload. If you have both data and notification in your payload, the pop up cannot be handled by your displayNotification method. You will need a data only payload.
Google has placed this behavior in the documentation.
Reference - FCM for android: popup system notification when app is in background
AutoCancel
For your second issue, add the setAutoCancel in your builder
.setAutoCancel(true)
Extra note
For some devices like Xiaomi and Redmi, you need to go to Settings to enable floating notification

Notification bar icon turns white in Android from FCM

I know that to support Lollipop Material design guidelines we have to make notification icon as transparent.
Here is my FCM onMessageReceived() function to show noticication.
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
NotificationCompat.Builder mBuilder;
mBuilder = new NotificationCompat.Builder(this)
.setContentTitle(remoteMessage.getNotification().getBody()) // title for notification
.setContentText(remoteMessage.getNotification().getTitle()) // message for notification
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setSmallIcon(getNotificationIcon())
.setAutoCancel(true); // clear notification after click
Intent intent = new Intent(this, CheckInListPage.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,Intent.FLAG_ACTIVITY_NEW_TASK);
mBuilder.setContentIntent(pi);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
private int getNotificationIcon() {
boolean useWhiteIcon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
return useWhiteIcon ? R.drawable.logo_a_transparent : R.drawable.logo_notifc;
}
But here my issue is that when the application is running in foreground and visible, it will take my logo_a_transparent and will get desired result (screenshot - first icon in the notification bar).
But when we are pausing the application and an FCM push came, It takes my app icon (android:icon="#drawable/ic_launcher") as notification icon became white (screenshot - second icon in the notification bar).
Replacing app icon as transparent will work, But not a correct solution.
Add this line in your menifestfile set your resource as your choice add this one
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#mipmap/ic_notification" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#android:color/transparent" />
With FCM, you can send two types of messages to clients applicatin
1) Notification messages,
2) Data messages
Here fcm doumentation
Notification Message calls onMessageReceived() only when the application is foreground. Notification messages are delivered to the notification tray when the app is in the background that's automatically handled by Android system rather than calling onMessageReceived(), The system uses app icon as notification icon that's why icon became white in background push. The android application needs not to be transparent.
In the case of Data Message whether the app is in the background or the foreground it will always be handled by onMessageReceived().
Data Message
{ "to" : "Ahd8fsdfu78sd...", "data" : {
"Name" : "...",
"body" : "...",
}
}
So I should use a data-only message payload or Messages with both notification and data payloads, so my onMessageReceived() can handle this and correct notification icon will displayed.
Fix at firebase 12.0.0. Just update your build.gradle to 12.0.0
https://firebase.google.com/support/release-notes/android#20180320

How to show a notification without a sound java

How can I make a notification that doesn't make a sound when I build it? I am building a notification, and my users don't like the fact that it makes a sound.
How can I change it to a silent one / no sound at all?
How I show notification:
android.support.v7.app.NotificationCompat.Builder builder = new android.support.v7.app.NotificationCompat.Builder(main);
builder.setStyle(new android.support.v7.app.NotificationCompat.BigTextStyle().bigText(text));
builder.setSmallIcon(R.drawable.app);
builder.setContentTitle("Rooster Maandag:");
builder.setOngoing(false);
builder.setAutoCancel(true);
builder.setSilent(true);
builder.setDefaults(Notification.DEFAULT_ALL);
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
notificationManager = (NotificationManager) main.getSystemService(main.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
I tried to search on google, but the only results I get is HOW to play a sound, not HOW to not play a sound...
Edit
It possibly is a duplicate in some people's eyes, but in mine I could not find out an alternative for the there specified default, while this new method is called setDefaults
To disable the sound in OREO 8.1, change the priority of the notification as LOW and it will disable the sound of notification:
NotificationManager.IMPORTANCE_LOW
The code is like:
NotificationChannel chan1 = new NotificationChannel("default", "default", NotificationManager.IMPORTANCE_LOW);
It works for me in Android Oreo.
You should just write your channel like this:
NotificationChannel notificationChannel = new NotificationChannel("Id" , "Name", NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setSound(null, null);
notificationChannel.setShowBadge(false);
notificationManager.createNotificationChannel(notificationChannel);
NotificationCompat.Builder.setSilent(true)
This works regardless of the Notification Channel setting. This allows you to have a channel that makes sound by default but allows you to post silent notifications if desired without making the entire channel silent.
Reference:
https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder#setSilent(boolean)
Remove the line to builder.setDefaults(Notification.DEFAULT_ALL);. It will not play the sound, but you may need to enable all other notification defaults if preferred
I might be late but still wants to add this . You can disable sound using .setSound(null) on NotificationCompat.Builder builder for all OS below O.
For O version n above add channel.setSound(null,null) after creating NotificationChannel channel
All the solutions above mine is either outdated or covers some OS versions only
In android O, for me it worked with this settings in the notification:
.setGroupAlertBehavior(GROUP_ALERT_SUMMARY)
.setGroup("My group")
.setGroupSummary(false)
.setDefaults(NotificationCompat.DEFAULT_ALL)
i had used this piece of code in NotificationCompat.Builder try this,
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setNotificationSilent();
Use this If you want all (sound, vibration and lights) in notifications.
builder.setDefaults(Notification.DEFAULT_ALL);
Or you can enable or disable items based on your requirements.
builder.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
comment this line if you want nothing.
Easy way to go to be able to show notification with any kind of priority is to set some sound that is silence actually. Just generate some silence.mp3 put it in "raw" folder and set notification sounds using Uri:
Uri.parse("android.resource://"+YOUR_APP_PACKAGE_NAME+"/"+R.raw.silence)
You can generate this .mp3 with app like Audacity. It has option generate silence, just set how many seconds and you are good to go.
If you set defaults to 0 and set sound to null, notification will be shown without you hearing it but you wont be able to show notifications with some higher priority.
use that exact code:
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_DEFAULT);
NOTIFICATION_CHANNEL_ID --> random String.
channelName ==> random string
You can set more than one channel.
In my case, my aplication has a background service with two sounds notifications, and one notification without sound. I get it with this code:
//creating channels:
NotificationChannel channel1 = new NotificationChannel(CHANNEL_ID_1, "CarNotification1", NotificationManager.IMPORTANCE_HIGH);
NotificationChannel channel2 = new NotificationChannel(CHANNEL_ID_2, "CarNotification2", NotificationManager.IMPORTANCE_MIN);
NotificationChannel channel3 = new NotificationChannel(CHANNEL_ID_3, "CarNotification3", NotificationManager.IMPORTANCE_HIGH);
//mSound1 and mSound2 are Uri
channel1.setSound(mSound1, null);
channel3.setSound(mSound2, null);
and when I create the notification:
String channelId;
switch (situation){
case situation2:
channelId=CHANNEL_ID_2;
break;
case situation1:
channelId=CHANNEL_ID_1;
break;
default:
channelId=CHANNEL_ID_3;
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId);
//etcetera

Categories