How to play different sound files on local notifications - android

Local notifications pop up when my Xamarin phone app receives a new event. This works fine, and it also plays a sound. However I want to play different sounds depending on the type of event that my app has received. I thought this would be simple enough, but whatever sound is played first after I rebuild the app, that is the sound that then plays for every notification regardless of the code.
For example, after rebuild, if Priority enum is Priority.Temp then TempNotif.wav will play. But if the code calls this method again to show another notification and Priority enum isn't Priority.Temp, TempNotif.wav still plays, even though I have set it to play StandardNotif.wav. It seems like android takes a copy of the first sound and doesn't bother updating it once there is a sound in place. Whatever is happening, surely I can play different sounds for different notifcations?
Here is code:
public void CreateNotification(string title, string message, Priority priority)
{
Android.Net.Uri sound = null;
if (priority == Priority.Temperature)
{
sound = global::Android.Net.Uri.Parse($!{ContentResolver.SchemeAndroidResource}://{context.PackageName}/{Resource.Raw.TempNotif}");
}
else
{
sound = global::Android.Net.Uri.Parse($!{ContentResolver.SchemeAndroidResource}://{context.PackageName}/{Resource.Raw.StandardNotif}");
}
var alarmAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Sonification)
.SetUsage(AudioUsageKind.Notification).Build();
builder = new NotificationCompat.Builder(context, notificationChannelId);
builder.SetContentTitle(title)
.SetAutoCancel(true)
.SetContentText(message)
.SetPriority((int)NotificationPriority.High)
.SetSmallIcon(Resource.Drawable.MetroIcon)
.SetColor(00255)
.SetVibrate(new long[0])
.SetSound(sound)
.SetVisibility((int)NotificationVisibility.Public);
notificationManager = context.GetSystemService(Context.NotificationService) as
NotificationManager;
if (global::Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
NotificationImportance importance = NotificationImportance.High;
NotificationChannel notificationChannel = new NotificationChannel(notificationChannelId,
title, importance);
notificationChannel.Importance = NotificationImportance.High;
notificationChannel.EnableLights(true);
notificationChannel.EnableVibration(true);
notificationChannel.SetSound(sound, alarmAttributes);
notificationChannel.SetShowBadge(true);
notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 });
if (notificationManager != null)
{
builder.SetChannelId(notificationChannelId);
notificationManager.CreateNotificationChannel(notificationChannel);
}
}
notificationManager.Notify(0, builder.Build());
}

Credit to #Mooniean for the answer!
The answer is to provide a different channel ID for each type of notification I want to display.
I set two static values for channel ID's and provide one depending on the type of notification I want to display.
private static string StandardchannelId = "1000";
private static string TempChannelId = "2000";
Here I assign my channelID depending on an enum I made:
if (priority == Priority.Temperature)
{
this.channelId = TempChannelId;
sound = global::Android.Net.Uri.Parse($"{ContentResolver.SchemeAndroidResource}://{context.PackageName}/{Resource.Raw.TempNotif}");
}
else
{
this.channelId = StandardchannelId;
sound = global::Android.Net.Uri.Parse($"{ContentResolver.SchemeAndroidResource}://{context.PackageName}/{Resource.Raw.StandardNotif}");
}
And here I assign the channelID:
builder.SetChannelId(this.channelId);

Related

Android push header/heads-up notification doesn't work

I am currently trying to get a header notification on a Nexus S (API 29), but with no success. I've seen some threads with various solutions, but none of them worked. The code is as follows:
Context applicationContext = getApplicationContext();
NotificationCompat.Builder builder = new NotificationCompat.Builder(applicationContext, CHANNEL_ID)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setDefaults(NotificationCompat.DEFAULT_SOUND)
.setSmallIcon(R.drawable.ic_account_circle)
.setContentTitle(notificationTitle)
.setContentText(notificationTextBody)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setLights(Color.RED, 3000, 3000);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(applicationContext);
int notificationId = new Random().nextInt();
//launches the notification on the device
notificationManager.notify(notificationId, builder.build());
I have tried setting sound on, vibrations on, to set the priority as high or max. I have even used the method setFullScreenIntent, separately and all at once, but nothing accomplished, what I seek.
on Android 8+ you have to create notification channel, like in DOC
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.channel_name);
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
note that channel also have importance. if you want a heads-up notification you have to set high priority for this channel, DOC
Example conditions that might trigger heads-up notifications include the following:
The notification channel has high importance on devices running Android 8.0 (API level 26) and higher.

How to play sometimes sound in notifications

I have this code to show a notification which is working as far as to show the notification, but when i run this function again, i dont get any sound.
public NotificationManager nm;
...
void ShowNotification(string title = "", string message = "", string header = "", bool notify = false)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
CreateSilentNotificationChannel();
}
var text = GetText(Resource.String.Local_service_label);
// Set the icon, scrolling text and timestamp
var sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
var msSinceEpoch = (long)sinceEpoch.TotalMilliseconds;
PendingIntent contentIntent = PendingIntent.GetActivity(this, 0, new Intent(this, typeof(MainActivity)), 0);
PendingIntent refreshIntent = PendingIntent.GetActivity(this, 0, new Intent(this, typeof(LocalService)), 0);
Android.Net.Uri uri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, currentNotId);
builder.SetContentTitle(GetString(Resource.String.OddEven_Notifications_AlertTitle))
.SetContentIntent(contentIntent)
.SetSmallIcon(Resource.Mipmap.ic_launcher)
.SetTicker(text)
.SetWhen(msSinceEpoch)
.SetAutoCancel(false)
.SetOngoing(true)
.SetUsesChronometer(true)
.SetShowWhen(true)
.SetContentTitle(title)
.SetVisibility((int)NotificationVisibility.Public)
.SetSubText(header)
.SetLargeIcon(BitmapFactory.DecodeResource(this.Resources, Resource.Mipmap.ic_launcher))
.SetContentText(message);
if (notify)
{
builder.SetVibrate(new long[] { 0, 400, 200, 200 });
builder.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification));
}
StickyNotification = builder.Build();
if (Build.VERSION.SdkInt < BuildVersionCodes.O && notify)
{
StickyNotification.Vibrate = new long[] { 0, 400, 200, 200 };
}
nm.Notify(NOTIFICATION, StickyNotification);
}
private void CreateSilentNotificationChannel()
{
var channelDescription = "SilentChannelForOddEvenNotification";
var chan1 = new NotificationChannel(notIDSilent, GetString(Resource.String.app_name), NotificationImportance.High)
{
Description = channelDescription,
Name = GetString(Resource.String.app_name),
};
// set the channel properties
chan1.EnableLights(true);
chan1.LightColor = Color.Red;
chan1.SetSound(null, null);
chan1.EnableVibration(false);
chan1.SetBypassDnd(true);
chan1.LockscreenVisibility = NotificationVisibility.Public;
// finally create the notification channel
//var manager = (NotificationManager)GetSystemService(NotificationService);
nm.CreateNotificationChannel(chan1);
}
i'm running the function ShowNotification() every 5 minutes but if i have the property notify true or false, i don't get any sound, why?
What is the proper way to have a sticky notification that we update regularly and sometimes we want to also have sound?
In the notification payload of the notification there is a sound key.
From the official documentation its use is:
Indicates a sound to play when the device receives a notification. Supports default or the filename of a sound resource bundled in the app. Sound files must reside in /res/raw/anySound.
{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "myicon",
"sound" : "default"
}
}
In the notification payload either you can use "sound" : "default" OR "sound" : "anySound"
In your case might be these lines are problematic
chan1.SetSound(null, null);
if (notify){
builder.SetVibrate(new long[] { 0, 400, 200, 200 });
builder.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification));
}
Beginning with Android 8.0 (Oreo), it would better to set the sound or the proority in Channel. And use the two ways below instead of chan1.SetSound(null, null);.
Use the specific ringtone for notification.
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var alarmAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Sonification)
.SetUsage(AudioUsageKind.Notification).Build();
var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Default)
{
Description = "Firebase Cloud Messages appear in this channel"
};
channel.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Ringtone),alarmAttributes);
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
For more details, please refer to the link below. specific ringtone firebase notification xamarin.android
Use the custom sound for notification.
void CreateNotificationChannel1()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var alarmAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Sonification)
.SetUsage(AudioUsageKind.Notification).Build();
var path = Android.Net.Uri.Parse("android.resource://com.companyname.NotificationChannelsDemo/" + Resource.Raw.Hello);
var name = Resources.GetString(Resource.String.channel_name);
var description = GetString(Resource.String.channel_description);
var channel = new NotificationChannel(CHANNEL_ID1, name, NotificationImportance.Max)
{
Description = description
};
channel.SetSound(path, alarmAttributes);
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
For more info, please check the link below. Custom Notification Sound FireBase

Notification vibrates on each progress update

When on Android 8.0 (Oreo), every time there is an update to the progress of the notification, it vibrates. So the phone vibrates 100 times in the process. This only happens on Android 8.0 So i can assume I am having some improper use of their API. I am asking for help in stopping the vibration on each progress update of the notification. Here is my code:
Building Notification
mNotifyManager = (NotificationManager) mActivity.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createChannel(mNotifyManager);
mBuilder = new NotificationCompat.Builder(mActivity, "FileDownload")
.setSmallIcon(android.R.drawable.stat_sys_download)
.setColor(ContextCompat.getColor(mActivity, R.color.colorNotification))
.setContentTitle(mFile.getName())
.setContentText(mActivity.getResources().getString(R.string.app_name))
.setProgress(0, 0, true);
mNotifyManager.notify(mFile.getId().hashCode(), mBuilder.build());
Create Channel method
#TargetApi(26)
private void createChannel(NotificationManager notificationManager) {
String name = "FileDownload";
String description = "Notifications for download status";
int importance = NotificationManager.IMPORTANCE_MAX;
NotificationChannel mChannel = new NotificationChannel(name, name, importance);
mChannel.setDescription(description);
mChannel.enableLights(true);
mChannel.setLightColor(Color.BLUE);
notificationManager.createNotificationChannel(mChannel);
}
onProgress
#Override
public void onProgress(File file, double progress, long downloadedBytes, long totalBytes) {
mBuilder.setProgress(100, (int) (progress * 100), false);
mNotifyManager.notify(file.getId().hashCode(), mBuilder.build());
}
Using setOnlyAlertOnce(true) on your NotificationCompat.Builder when initially building the notification should do the trick.
Try to disable vibration like this :
notificationBuilder.setDefaults(Notification.DEFAULT_LIGHT | Notification.DEFAULT_SOUND)
.setVibrate(new long[]{0L});
Another option is to set .setNotificationSilent() on your update notifications.

Android Oreo notification keep making Sound even if I do not set sound. On Older version, works perfectly

So I am making my app compatible with Oreo and facing issue with notification.
I added notification channel according to documentation and everything is working smooth except notification keep making sound on every posting, tried setting defaults to 0 as well.
I am testing my app in emulator, any help is highly appreciated.
Used this code for creating channel
NotificationCompat.Builder builder = new NotificationCompat.Builder(PlayerService.this, "channel_01")
.setAutoCancel(false)
.setContentIntent(pendingIntent)
.setContent(viewsSmall)
.setCustomBigContentView(viewsExpanded)
.setDeleteIntent(pSwipeToDismiss);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setVisibility(Notification.VISIBILITY_PUBLIC);
}
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
builder.setPriority(Notification.PRIORITY_MAX);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
/* Create or update. */
NotificationChannel channel = new NotificationChannel("channel_01",
"Playback Notification",
NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
mBuilder.setChannelId("channel_01");
}
final Notification notification = builder.build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,notification);
Take a look at the notification channel settings (swipe your notification and press the settings icon under it and then select your channel). Those settings are set the first time you create the channel and then not modified unless you do it manually in the device (at least that is my experience from uninstalling and reinstalling my app to see what settings I get by default).
Basically, channel.setSound(null, null) will only have effect when you create the channel on a fresh installation. That might be what they try to explain in the official guide:
Attempting to create an existing notification channel with its original values performs no operation
If you tried to follow that guide and set NotificationManager.IMPORTANCE_HIGH and didn't use channel.setSound(null, null), the channel would get importance level Urgent Make sound and pop on screen with the default sound.
^Benjamin answer works but he is missing some important detail! You must change your channel ID each time you adjust your code or Oreo will not make the changes. Not sure why.
My code below and you can see where the chnage must be made with this <-------here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelID = "My Channel I"; <-------here
String appName = mContext.getResources().getString(R.string.app_name);
NotificationCompat.Builder notificationCompatBuilder = new NotificationCompat.Builder(mContext );
notificationCompatBuilder
.setOngoing(true)
.setContentTitle(mContext.getResources().getString(R.string.app_name))
.setContentText(mContext.getString(R.string.clocked_in))
.setSmallIcon(R.drawable.ic_action_name)
.setChannelId(channelID)
.setSound(null);
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel notificationChannel = new NotificationChannel(channelID, appName, NotificationManager.IMPORTANCE_LOW);
notificationChannel.setSound(null, null);
notificationManager.createNotificationChannel(notificationChannel);
notificationManager.notify(ONGOINGNOTIFICATION_ID, notificationCompatBuilder.build());
}
Replace your code with this
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
/* Create or update. */
NotificationChannel channel = new NotificationChannel("channel_01",
"Playback Notification",
NotificationManager.IMPORTANCE_LOW);
channel.setSound(null, null);
mNotificationManager.createNotificationChannel(channel);
mBuilder.setChannelId("channel_01");
}
My scene is the first time there is a sound, and the update notification does not require a sound.
I use this setOnlyAlertOnce() method
Reference: https://developer.android.com/training/notify-user/build-notification#Updating
Test pass version 26

Disable vibration for a notification

I'm writing an app using notification. Google developer guidelines encourages developers to provide settings to customize the notifications (disable vibration, set notification sound...), so I am trying to disable vibration for notifications if the user set it that way.
I am using NotificationCompat.Builder to create the notification, like this:
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(Application.getContext())
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(Notification.PRIORITY_MAX)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(largeIconBitmap)
.setAutoCancel(true)
.setContentIntent(resultPendingIntent)
.setContentTitle(title)
.setContentText(content);
I tried different ways to disable notifications:
notificationBuilder.setVibrate(null);
notificationBuilder.setVibrate(new long[]{0l, 0l});
notificationBuilder.setDefaults(Notification.DEFAULT_ALL | ~Notification.DEFAULT_VIBRATE);
notificationBuilder.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND);`
I also tried to build the notification and change values on the resulting object:
Notification notification = notificationBuilder.build();
notification.vibrate = null;
But the phone still vibrates when the notification appears.
How can I disable vibration for notifications?
After a long trial & error session, I think I finally understood what's wrong.
The problem lies in this instruction notificationBuilder.setDefaults(Notification.DEFAULT_ALL).
No matter what parameter you pass to notificationBuilder.setVibrate() after setting DEFAULT_ALL or DEFAULT_VIBRATE will be silently discarded. Someone at Google must have decided to give a higher precedence to setDefaults than to setVibrate.
This is how I ended up disabling vibration for notifications in my app:
notificationBuilder.setDefaults(Notification.DEFAULT_LIGHT | Notification.DEFAULT_SOUND)
.setVibrate(new long[]{0L}); // Passing null here silently fails
This works but doesn't feel right to initialize a new long[] just to disable the vibration.
In the year 2020:
Setting the importance of the notification channel to NotificationManager.IMPORTANCE_NONE worked for me.
They are not stop because you are use "setDefaults(Notification.DEFAULT_ALL)" so if you need to stop vibration and sound remove this line , or if you need to use the default sound and stop vibration I think you must use setDefaults(Notification.DEFAULT_SOUND) etc ...
You have 2 solutions with the notification channel.
Set a "fake" pattern to disable the vibration.
Set Importance flag, but less flexible (see https://developer.android.com/training/notify-user/channels#importance). Takes care, it will also impact some other stuff like priority...
As a result, you can use
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
// no vibration
channel.setVibrationPattern(new long[]{ 0 });
channel.enableVibration(true);
Or
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
.setVibrate(null) works for me - and a better solution than creating a needless long[].
Result: device doesn't vibrate and no grumbling in LogCat either. :)
notification.vibrate = new long[] { -1 };
this code work for me.
Above solutions didnt work but adding mBuilder.setOnlyAlertOnce(true); to my notification builder solved my problem.
if (mBuilder == null) {
String channelId = "channel-id";
String channelName = "Channel Name";
int importance = NotificationManager.IMPORTANCE_MAX;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
channelId, channelName, importance);
mChannel.setSound(null, null);
mChannel.enableVibration(false);
notificationManager.createNotificationChannel(mChannel);
}
mBuilder = new NotificationCompat.Builder(Application.context, channelId);
mBuilder.setSmallIcon(R.drawable.ic_ulakbel)
.setContentTitle("YOURTITLE")
.setAutoCancel(true)
.setColor(ContextCompat.getColor(Application.context, R.color.green))
.setColorized(true);
mBuilder.setChannelId(channelId);
mBuilder.setPriority(1);
mBuilder.setCustomContentView(notificationLayout);
mBuilder.setCustomBigContentView(notificationLayout);
mBuilder.setOnlyAlertOnce(true);
notificationManager.notify(1452, mBuilder.build());
}else{
Notification notification = mBuilder.build();
notification.flags = Notification.FLAG_ONGOING_EVENT;
notificationManager.notify(1452,notification);
}
private void removeSoundAndVibration(Notification notification) {
notification.sound = null;
notification.vibrate = null;
notification.defaults &= ~DEFAULT_SOUND;
notification.defaults &= ~DEFAULT_VIBRATE;
This code is from Notification Compat Api Class. This should work, add all these to your builder.
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Example Service Channel",
NotificationManager.IMPORTANCE_MIN
);
serviceChannel.setVibrationPattern(new long[]{ 0 });
serviceChannel.enableVibration(true);
serviceChannel.enableLights(false);
serviceChannel.setSound(null, null);
serviceChannel.setShowBadge(false); //
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
If you make IMPORTANCE_MIN that you can disabled vibration, if you make IMPORTANCE_DEFAULT it happens vibration so you can try IMPORTANCE_MIN
July 2022: I have tried everything in this thread, and the only thing that worked was Zhar's suggestion to set importance to low:
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
I am targeting Android API level 24.
setVibrate(new long[0]) works if you're targetting API 28. I'm working with chinese smartwatches running smartphone android roms so in the rest of the devices should work fine. Hope it helps!

Categories

Resources