Oreo & Pie Notifications - java

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);

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);

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

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

Android NotificationCompat.Builder works with three buttons but not four

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.

Is it possible to set an Android Notification or a later date and time that will fire when the app is not running?

From what I have read it seems that code like this would require the app to be running in a thread until the notification fires. I need the notification to fire at a later date and time so the user sees the notification just like any other notification and then clicks it and it opens of an activity, passing in some data so the app knows what to do.
How can I make this notification fire days later without the app running the whole time?
Do I use wait to accomplish this?
long millis = 60000;
myNotification.wait(millis);
Here is my code which fires immediately
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(getActivity())
.setSmallIcon(R.drawable.star)
.setContentTitle("How was " + me.getString("EventTitle") + "?")
.setContentText("Click here to leave your review");
Intent resultIntent = new Intent(getActivity(), SetupActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
getActivity(),
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
int mNotificationId = me.getInt("EventID");
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) getActivity().getSystemService(getActivity().NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
As A--C wrote, use AlarmManager to schedule a PendingIntent to be invoked at your desired time. You will probably use an RTC_WAKEUP alarm, meaning "the time is based on System.currentTimeMillis(), like Calendar uses" and "let's wake up the device out of sleep mode". Use a broadcast PendingIntent, and your Notification code can go into the onReceive() method, if you do not need to do any disk or network I/O to get the information to use for the Notification itself.
Note that in Android 4.4 the rules for AlarmManager changed a bit. You will want to use setExact() on Android 4.4+ and set() on earlier Android versions.

Categories