In my hybrid Cordova Android app targeting API 23+ I want to use a custom sound for notifications. To that end I have done the following
In plugin.xml file for the single custom plugin I use in the app I declare <resource-file src="src/android/res/unysound.mp3" target="res/raw/mysound.mp3" />'.
Opening the APK as a zip archive I see that the mp3 file has in fact ended up in `res/raw/mysound.mp3'.
- When building the notification I do the following
Notification notification = new Notification.Builder(context)
.setDefaults(0) //turns off ALL defaults
.setVibrate(vibrate) /sets to vibrate
....
.setSound(uri).build();
where
Uri uri = Uri.parse("android.resource://" + ctxt.getPackageName() + "/raw/mysound.mp3");
This appears to be the recipe indicated in a number of articles I find on a spot of googling and even in other threads on SO. And yet, when I issue a notification I do not hear the expected sound. What might I be doing wrong?
The answer below does not help since in the context of my hybrid Cordova app with a custom plugin attempting to build the APK throws up an error along the lines of class R not known/found...
below code will help you:
String CHANNEL_ID="1234";
Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"+ getApplicationContext().getPackageName() + "/" + R.raw.mysound);
NotificationManager mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
//For API 26+ you need to put some additional code like below:
NotificationChannel mChannel;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mChannel = new NotificationChannel(CHANNEL_ID, Utils.CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
mChannel.setLightColor(Color.GRAY);
mChannel.enableLights(true);
mChannel.setDescription(Utils.CHANNEL_SIREN_DESCRIPTION);
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
mChannel.setSound(soundUri, audioAttributes);
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel( mChannel );
}
}
//General code:
NotificationCompat.Builder status = new NotificationCompat.Builder(getApplicationContext(),CHANNEL_ID);
status.setAutoCancel(true)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.logo)
//.setOnlyAlertOnce(true)
.setContentTitle(getString(R.string.app_name))
.setContentText(messageBody)
.setVibrate(new long[]{0, 500, 1000})
.setDefaults(Notification.DEFAULT_LIGHTS )
.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE+ "://" +mContext.getPackageName()+"/"+R.raw.apple_ring))
.setContentIntent(pendingIntent)
.setContent(views);
mNotificationManager.notify(major_id, status.build());
where mysound is my ringtone which is put under res/raw folder.
Note: you have to only put name of ringtone without extension like raw/mysound
Note: In Android Oreo you must change your channel ID to changes take effect. And before Oreo version, using ".setDefaults()" seens prevent custom sound to play.
Try clearing data (or fresh install)
Trying this again
The settings are set the first time you create the channel and then not modified unless you do it manually by fresh install or clearing data.
For more info on this read the top answer here:
Android Oreo notification keep making Sound even if I do not set sound. On Older version, works perfectly
For API 26+ you need to set the sound on the notification channel:
Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"+ getApplicationContext().getPackageName() + "/" + R.raw.siren);
NotificationManager mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel mChannel;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mChannel = new NotificationChannel(Utils.CHANNEL_SIREN_ID, Utils.CHANNEL_SIREN_NAME, NotificationManager.IMPORTANCE_HIGH);
mChannel.setLightColor(Color.GRAY);
mChannel.enableLights(true);
mChannel.setDescription(Utils.CHANNEL_SIREN_DESCRIPTION);
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
mChannel.setSound(soundUri, audioAttributes);
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel( mChannel );
}
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, Utils.CHANNEL_SIREN_ID)
.setSmallIcon(R.drawable.ic_stat_maps_local_library)
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.mipmap.ic_launcher))
.setTicker(title)
.setContentTitle(contentTitle)
.setContentText(contentText)
.setAutoCancel(true)
.setLights(0xff0000ff, 300, 1000) // blue color
.setWhen(System.currentTimeMillis())
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
mBuilder.setSound(soundUri);
}
int NOTIFICATION_ID = 1; // Causes to update the same notification over and over again.
if (mNotificationManager != null) {
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
you can call this method while handling notification
public void playNotificationSound() {
try {
Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
+ "://" + mContext.getPackageName() + "/raw/notification");
Ringtone r = RingtoneManager.getRingtone(mContext, alarmSound);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
}
Notification.Builder builder = new Notification.Builder(context);
builder.setContentTitle(mTitle);
builder.setContentText(mContentText);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
builder.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
builder.setDefaults(Notification.DEFAULT_ALL);
Use this to work with sound, I hope it will solve your problem, Cheers!
Use this for setting sound
Uri defaultSoundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + mContext.getPackageName() + "/raw/mysound");
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(mContext)
.setContentIntent(mainPIntent)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_launcher))
.setContentTitle("" + title)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentText("" + body);
NotificationManager mNotificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(title, NOTIFICATION_ID, mBuilder.build());
You are accessing the sound in a subfolder in the resources
change the source of your uri to
Uri uri = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.siren);
For the default sound, use:
notification.defaults |= Notification.DEFAULT_SOUND;
I am not sure but i think issue is that you are doing the wrong way "/raw/mysound.mp3 :
Uri uri = Uri.parse("android.resource://" + ctxt.getPackageName() + "/raw/mysound.mp3");
First add the permission in manifest : uses-permission android:name="android.permission.VIBRATE" />
then you can set the default sound like :-
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder.setSound(alarmSound);
and for vibration:
mBuilder.setVibrate(new long[] { 1000, 1000});
for custom sound, put mp3 file on this path:Res\raw\sound.mp3
and then
Notification notification = builder.build();
notification.sound = Uri.parse("android.resource://"
+ context.getPackageName() + "/" + R.raw.sound);
Related
I am getting the custom sound name from the notification and added conditions based on key but always sound only playing in my notification.
I want to play different sounds based on sound keys and how to handle anyone have ideas to help the same.
if (playOrderAssignmentTone) {
if(key.equalsIgnoreCase("sound")){
alarmSound = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.sound);
} else {
alarmSound = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.sound2);
}
} else {
alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
} catch (Exception e) {
LoggerUtility.PrintTrace(e);
FirebaseCrashlytics.getInstance().log(e.getMessage());
FirebaseCrashlytics.getInstance().recordException(e);
alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
Notification Builder
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, CHANNEL_ONE_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle(notificationTitle)
.setContentText(notificationBody)
//Optional fields
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_STATUS)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setTicker(notificationTicker)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setWhen(System.currentTimeMillis())
//.setSound(alarmSound)
//.setShowWhen(true)
.setOngoing(isOngoing);
// Setting notification sound based on channel id
if (!CHANNEL_ONE_ID.equalsIgnoreCase("auto")) {
notificationBuilder.setSound(alarmSound);
}
So the issue with your code is you need to make separate notification channels for different sounds to work. Above is the code to attach a sound to the notification channel.
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
Uri audio = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + File.pathSeparator + File.separator
+ File.separator + getApplicationContext().getPackageName() + File.separator + R.raw.notification);
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION).build();
channel.setSound(audio, attributes);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
}
So when you want to play some specific sound with a notification use that notification CHANNEL_ID with the notification builder.
You have to call setSound() method on NotificationChannel instance.
val audioAttributes = AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH).apply {
setSound(soundUri, audioAttributes)
}
select notification tone from your mobile:
Uri ringtone=RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);;
Intent intent=new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, ringtone);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, ringtone);
((Activity) getContext()).startActivityForResult(intent , 1);
get ringtone path in onActivity result:
if (resultCode == MainActivity.RESULT_OK && requestCode == 1) {
uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
path = uri.toString();
}
saving this path in sqlite database and retrive from in service
when you trigger your notification play this sound just once:
Uri uri;
uri = Uri.parse(myDb.alarmGetRingtone(requestcode));
r = RingtoneManager.getRingtone(getApplicationContext(), uri);
r.play();
I Hope This Code Will Help You
Thank You
Be informed we are trying to send push notification to a device with custom sound. The custom mp3 file (120 seconds) is stored in res/raw file. The notification is sent successfully, but the sound never plays out even after many tries. The code is as given below:
Update:Based on suggestion given in the comments, created a notificationchannel and set the sound in it, but still its not working. Worse, unable to build apk at all.
Uri soundUri= Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + BuildConfig.APPLICATION_ID + "/" + R.raw.adhan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, MainActivity.asw_fcm_channel)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent);
Notification noti = notificationBuilder.build();
noti.flags = Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.FLAG_AUTO_CANCEL;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel("345",
"new",
NotificationManager.IMPORTANCE_HIGH);
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
// Configure the notification channel.
mChannel.setDescription(message);
mChannel.enableLights(true);
mChannel.enableVibration(true);
mChannel.setSound(soundUri, attributes); // This is IMPORTANT
if (NotificationManager != null)
NotificationManager.createNotificationChannel(mChannel);
}
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notification_id, notificationBuilder.build());
We are at loss as where we are going wrong. Please guide us as how we solve this issue.
I am adding custom sound for my application. The custom ringtone is playing when the application is in the foreground but the custom sound is not playing when the application is in background.
private void sendMyNotification(String message) {
Intent intent = new Intent(this, BaseActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
Uri soundUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/" + R.raw.ring);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "CH_ID")
.setSmallIcon(R.mipmap.iconfinal)
.setContentTitle(getString(R.string.app_name))
.setContentText(message)
.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(1, notificationBuilder.build());
}
First you need to pass your sound file name from server side.
like below example:
{
"to": "firebase_notification_token",
"notification": {
"title": "Push notification title",
"body": "Push body",
"sound": "filename", <-- point to src/res/raw/filename.mp3
}
}
You need to add below code to play custom sound while app is in background.
val channelId = getString(R.string.app_name)
val NOTIFICATION_SOUND_URI =
Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + BuildConfig.APPLICATION_ID + "/" + R.raw.filename)
val notificationBuilder = NotificationCompat.Builder(this, channelId)
val notification: Notification
notification = notificationBuilder.setSmallIcon(R.drawable.ic_logo_white).setTicker(getString(R.string.app_name)).setWhen(0)
.setAutoCancel(true)
.setContentTitle(getString(R.string.app_name))
.setSound(NOTIFICATION_SOUND_URI)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText(messageBody)
.build()
For more detail refer to this Document.
Thanks to Ilya Eremin for great article.
Am trying to produce two type of custom notification sound by adding .wav file in raw folder, when notification like job comes it produce job related notification sound in other case if notification like message comes it produce message related notification sound.
I set channel if for get the notification in Higher end device,but after creating the channel id am getting same notification sound when a notification comes based on which type of notification comes first.
onMessageReceived
String sound = data.get("sound");
Uri soundUri = Uri.parse("android.resource://" + getPackageName() + "/raw/" + sound);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
.setSmallIcon(getNotificationIconId())
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setOnlyAlertOnce(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(messageBody));
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O && notificationManager != null) {
int importance = android.app.NotificationManager.IMPORTANCE_HIGH;
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
NotificationChannel mChannel = new NotificationChannel(
getString(R.string.default_notification_channel_id), Constants.NOTIFICATION_CHANNEL_NAME_MESSAGE, importance);
mChannel.setSound(soundUri,audioAttributes);
notificationManager.createNotificationChannel(mChannel);
}
if (notificationManager != null) {
notificationManager.notify(messageId, notificationBuilder.build());
}
Manifest
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id"/>`enter code here`
You need to create two notification channels, each channel for each sound and assign the ID of the channels depending on the sound you want to reproduce.
It is explained in the documentation that once a channel is created it cannot be modified.
I recently started coding my first android project including notifications (SDK 21 - Android 5)
Currently, I have a tiny little button, that creates a notification on click and sends it to the app itself. Sound foolish but the purpose is to test if a custom sound and vibrate pattern is used.
This is the notification that gets constructed on click:
Notification note = new Notification.Builder(this.requireContext(), "channel_id")
.setSmallIcon(R.mipmap.icon)
.setContentTitle("Title")
.setContentText("Text")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setVibrate(new long[] {500, 500, 500, 500, 500})
.setSound(SettingsHandler.getRingtoneUri(this.requireContext())
.setContentIntent(anyIntent)
.setAutoCancel(true)
.build();
SettingsHandler is a helper class I created to handle settings. Like switching vibration on and off or picking a ringtone. getRingtoneUri() does the following:
public synchronized static Uri getRingtoneUri(Context context) {
SharedPreferences prefs = context.getSharedPreferences("table_name", Context.MODE_PRIVATE);
return Uri.parse(prefs.getString("ringtone_uri_key", RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION).toString()));
}
When debugging this the result of getRingtoneUri is something like "content://media/internal/audio/media/31". This looks valid to me. However, in a later line, the sound property of the created notification is still null. Amy idea what I'm doing wrong? Thanks in forward.
try this:
Uri alarmSound = Uri.parse("android.resource://" + context.getPackageName() + "/raw/ding");
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, context.getString(R.string.checkout_channel));
mBuilder.setContentTitle(context.getString(R.string.passenger_name)).setContentText(context.getString(R.string.pit, name)).setSmallIcon(R.drawable.notification_icon).setSound(alarmSound);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String channelDescription = "Checkout Channel";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build();
NotificationChannel notificationChannel = new NotificationChannel(context.getString(R.string.checkout_channel),
channelDescription, notifManager.IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.GREEN);
notificationChannel.setShowBadge(true);
notificationChannel.setSound(alarmSound, audioAttributes);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
notificationManager.createNotificationChannel(notificationChannel);
}
notificationManager.notify(iUniqueId, notification);
You need to set the audioAttributes and create your notification channel. This works for me for all Android from 4.2 to 9