Android notification setSound is not working
Asked Answered
C

9

40

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...

Comras answered 26/2, 2018 at 10:57 Comment(0)
O
57

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.

Opuntia answered 6/3, 2018 at 6:27 Comment(8)
I am accepting your answer because it came closest to identifying the underlying issue - it is the extension mp3 that was causing the problem. Without the extension my original code delivers the desired result. Note that in a Cordova app R.java is not recognized so what you have shown above is not truly applicable.Comras
Why would you call setDefaults twice?Procne
I couldn't find CONTENT_TYPE_NOTIFICATION in AudioAttributes so I've omit that and the solution still works.Benenson
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.Janellejanene
@Janellejanene this is must. I spent one day just to rectify this issue.Wegner
I;ve used setSound() on my notification channel and passed in the sound Uri and the audioAttribute but still no sound. I have uninstalled and installed the app multiple times and yet no way forward.Hoberthobey
Please add @Janellejanene comment to your answer as a note. it saved me a lot of time.Schroer
i saw extension issue problem after 2 hours trying :'(Shrill
B
37
  1. Try clearing data (or fresh install)
  2. 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

Bedell answered 24/9, 2018 at 7:40 Comment(3)
I was getting frustrated that whatever sound or vibration settings I add to NotificationCompat.Builder or NotificationChannel it make no difference, until I cleared the app data and suddenly it worked. Thanks, your answer saved my day.Scoliosis
I spent hours trying to figure out why nothing is changing you saved my day, thank youPaeon
How to solve this issue, i had set vibration as a user preference so based on that user will change, but it works only for the fresh installSchacker
E
23

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());
    }
Enoch answered 25/9, 2018 at 20:37 Comment(2)
mChannel.setSound(soundUri, audioAttributes); is what made the sound work in OreoDarreldarrell
Thanks for this, This is not great, cause what if we want different sounds for different notifications within a channel.Velate
D
14

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();
    }
}
Dentelle answered 1/3, 2018 at 9:41 Comment(4)
An upvote here because I suspect that using ContentResolver as opposed to android.resource:// is a more future proof way of doing things.Comras
What you are doing here - via RingToneManager - works but it is not right and should not have to be done given that Notification.Builder has its own method to setSoundComras
Yea there are a lot of things in Android that should not have to be done, I have learned over the past 4 years, don't assume anything works properly or is done already for you in Android until you see it with your own eyes...FYIAugment
The only method that worked for me.Wisecrack
C
5
 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!

Cyclo answered 7/3, 2018 at 7:10 Comment(0)
S
1

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());
Scatology answered 6/3, 2018 at 5:24 Comment(0)
P
1

This is mentioned in the comments of another answer, but I think it bears repeating.

setSound(), enableVibration(), enableLights() - none of these options work on existing channels. Even if you try and be smart and call deleteNotificationChannel and re-create it - it will never work. You MUST create a new notification channel ID, and then all your changes will take effect.

Perlis answered 1/11, 2023 at 13:5 Comment(0)
S
0

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;
Scots answered 26/2, 2018 at 11:39 Comment(1)
The only problem is that when use R.raw.mysound.mp3 I cannot get the app to compile - the error R cannot be resolved to a variable. Remember that I have a Cordova project with a custom plugin. I am putting the notification, setsound etc code in that plugin along with the sound resource in questionComras
F
0

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);
Fourthclass answered 5/3, 2018 at 6:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.