Custom Notification Sound not working in Android Oreo

31,912

Solution 1

To set a sound to notifications in Oreo, you must set sound on NotificationChannel and not on Notification Builder itself. You can do this as follows

Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + R.raw.notification_mp3);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        NotificationChannel mChannel = new NotificationChannel("YOUR_CHANNEL_ID",
            "YOUR CHANNEL NAME",
            NotificationManager.IMPORTANCE_DEFAULT)

        AudioAttributes attributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .build();

        NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, 
                context.getString(R.string.app_name),
                NotificationManager.IMPORTANCE_HIGH);

        // Configure the notification channel.
        mChannel.setDescription(msg);
        mChannel.enableLights(true);
        mChannel.enableVibration(true);
        mChannel.setSound(sound, attributes); // This is IMPORTANT


        if (mNotificationManager != null)
            mNotificationManager.createNotificationChannel(mChannel);
    }

This will set a custom sound to your notifications. But if the app is being updated and the notification channel is used before, it won't be updated. i.e. you need to create a different channel and set sound to it to make it work. But this will show multiple channels in the notifications section of app info of your app. If you are setting sound to an entirely new channel that is fine, but if you want the channel being used before, you have to delete the existing channel and recreate the channel. To do that you can do something like that before creating channel

if (mNotificationManager != null) {
            List<NotificationChannel> channelList = mNotificationManager.getNotificationChannels();

            for (int i = 0; channelList != null && i < channelList.size(); i++) {
                mNotificationManager.deleteNotificationChannel(channelList.get(i).getId());
            }
        }

Solution 2

This might help the new comers.

Here is a code for a working notification sample on all android versions with all kinds of possible setups.

1 -> sound and vibration
2 -> sound but no vibration
3 -> no sound but vibration
4 -> no sound no vibration

OUTPUT

enter image description here

Github Repo -> https://github.com/usman14/Notification

CODE

MainActivity

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.Switch;

public class MainActivity extends AppCompatActivity {

    public boolean shouldSound;
    public boolean shouldVibrate;
    NotificationManager notificationManager;

    Button button;
    Switch soundSwitch;
    Switch vibrationSwitch;

    @TargetApi(Build.VERSION_CODES.O)
    public void registerNormalNotificationChannel(android.app.NotificationManager notificationManager) {

        NotificationChannel channel_all = new NotificationChannel("CHANNEL_ID_ALL", "CHANNEL_NAME_ALL", NotificationManager.IMPORTANCE_HIGH);
        channel_all.enableVibration(true);
        notificationManager.createNotificationChannel(channel_all);

        NotificationChannel channel_sound = new NotificationChannel("CHANNEL_ID_SOUND", "CHANNEL_NAME_ALL", NotificationManager.IMPORTANCE_HIGH);
        channel_sound.enableVibration(false);
        notificationManager.createNotificationChannel(channel_sound);

        NotificationChannel channel_vibrate = new NotificationChannel("CHANNEL_ID_VIBRATE", "CHANNEL_NAME_ALL", NotificationManager.IMPORTANCE_HIGH);
        channel_vibrate.setSound(null, null);
        channel_vibrate.enableVibration(true);
        notificationManager.createNotificationChannel(channel_vibrate);


        NotificationChannel channel_none = new NotificationChannel("CHANNEL_ID_NONE", "CHANNEL_NAME_ALL", NotificationManager.IMPORTANCE_HIGH);
        channel_none.setSound(null, null);
        channel_none.enableVibration(false);
        notificationManager.createNotificationChannel(channel_none);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.btn);
        soundSwitch = findViewById(R.id.switch_sound);
        vibrationSwitch = findViewById(R.id.switch_vibration);
        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (isOreoOrAbove()) {
            setupNotificationChannels();
        }

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                makeNotification();
            }
        });

        soundSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (b) {
                    shouldSound = true;
                } else {
                    shouldSound = false;
                }
            }
        });

        vibrationSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (b) {
                    shouldVibrate = true;
                } else {
                    shouldVibrate = false;
                }
            }
        });
    }

    private void setupNotificationChannels() {
        registerNormalNotificationChannel(notificationManager);
    }

    public void makeNotification() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this, getChannelId())
                .setContentTitle("Hi")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentText("Welcome to Android");

        Intent intent = new Intent(MainActivity.this, MainActivity.class);

        PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        builder.setContentIntent(pendingIntent);
        if (shouldSound && !shouldVibrate) {
            builder.setDefaults(Notification.DEFAULT_SOUND)
                    .setVibrate(new long[]{0L});
        }
        if (shouldVibrate && !shouldSound) {
            builder.setDefaults(Notification.DEFAULT_VIBRATE)
                    .setSound(null);
        }
        if (shouldSound && shouldVibrate) {
            builder.setDefaults(Notification.DEFAULT_ALL);
        }


        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, builder.build());
    }

    private String getChannelId() {
        if (shouldSound && shouldVibrate) {
            return "CHANNEL_ID_ALL";
        } else if (shouldSound && !shouldVibrate) {
            return "CHANNEL_ID_SOUND";
        } else if (!shouldSound && shouldVibrate) {
            return "CHANNEL_ID_VIBRATE";
        } else {
            return "CHANNEL_ID_NONE";
        }
    }

    private boolean isOreoOrAbove() {
        return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O;
    }
}

activity_main (xml)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">



    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:id="@+id/sound_layout"
        android:orientation="horizontal"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="SOUND SWITCH"></TextView>


        <Switch
            android:layout_marginLeft="50dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:id="@+id/switch_sound">

        </Switch>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/vibration_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/sound_layout">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="VIBRATION SWITCH"></TextView>


        <Switch
            android:layout_marginLeft="50dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:id="@+id/switch_vibration">

        </Switch>

    </LinearLayout>


    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send Notification"
        android:id="@+id/btn"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/vibration_layout"></Button>

</androidx.constraintlayout.widget.ConstraintLayout>
Share:
31,912

Related videos on Youtube

Ashish John
Author by

Ashish John

Try to learn android from any source

Updated on July 23, 2022

Comments

  • Ashish John
    Ashish John almost 2 years
    Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + R.raw.notification_mp3);
                mBuilder.setSound(sound);
    

    I had copied the mp3 (notification_mp3.mp3) file into the raw folder in the res folder. When the notification is triggered it produces given mp3 sound upto Android Nougat but default sound in Android Oreo. I had referred many sites but nothing worked on Android Oreo. I didn't find any changes in Android Docs regarding notification sound in Android O & above. What changes should be done to make this code working in Android O too?

    • CommonsWare
      CommonsWare about 6 years
      You set the sound on the notification channel, not on the notification, in Android 8.0+.
  • Najoua Mahi
    Najoua Mahi almost 6 years
    it's working perfectly, but only when app is in foreground. I stil have the default sound when app is in backgroun(for oreo). Do you have a solution for that?
  • Ankush
    Ankush almost 6 years
    @NajouaMahi Are you using Firebase Push Notifications?
  • Najoua Mahi
    Najoua Mahi almost 6 years
    yes i'm using Firebase, they offer meta-data for default notification icon and color if none of them exists, but I didn't find a meta-data for sound.Can you help please!
  • Ankush
    Ankush almost 6 years
    Have a look at this answer stackoverflow.com/a/37845174/2577750
  • Najoua Mahi
    Najoua Mahi almost 6 years
    Yes we need to send data messages, thank you Ankush, that helped
  • Biswanath Maity
    Biswanath Maity over 5 years
    I am facing same type of problem on my case everything is working fine except the custom sound when application in background or kill. Can you suggest any solution.
  • Ankush
    Ankush over 5 years
    @BiswanathMaity Have a look at this answer stackoverflow.com/a/37845174/2577750
  • TeachMeJava
    TeachMeJava over 5 years
    Where is mNotificationManager and mNotificationManager declarations?
  • Tulika
    Tulika about 5 years
    When creating the notification channel after deleting it, the system uses the old channel settings only. Anyone who has been able to change the sound of the notification channel using the above method, can you comment if anything else needs to be done.
  • AlexS
    AlexS almost 5 years
    This is not will work, because you sould use notification channels.
  • Daniel Wilson
    Daniel Wilson over 4 years
    Don't forget you need to reinstall the app otherwise it recycles the old notification channels some how
  • Luciano Brum
    Luciano Brum about 3 years
    Where is the custom sound ? this does not answer the question.
  • Nilesh Lathe
    Nilesh Lathe almost 3 years
    Unfortunately I tried lots of solution and this too but I am getting same default notification tone not custom anyone help?(I have copy pasted above code changed channel id also and then reinstalled it several times but still problem is not solved
  • Oliver D
    Oliver D about 2 years
    Hey 👋, I have an issue with Android 7 which is the channels are not supposed to be working there, so is there a way to change the notifications sound for it?
  • Abhinav Suman
    Abhinav Suman almost 2 years
    In Android Oreo and above. even deleting the channels and recreating them, is not working. In any case, you have to go for the new channels only.