java – Personalized sound when receiving a Notification

Question:

Hello I am creating an alarm, and I want to add a custom Ringtone but when trying to put the custom sound and run the app on a cell phone, it only gives the default tone and not the custom one, this is my code

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioAttributes;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;


import androidx.core.app.NotificationCompat;



public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {


        String message = intent.getStringExtra("todo");

        Intent mainIntent = new Intent(context, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* Request code */, mainIntent,
                PendingIntent.FLAG_ONE_SHOT);

        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        int notificationId = intent.getIntExtra("notificationId", 0);
        String channelId = "channel-01";
        String channelName = "Alarm Notification";
        int importance = NotificationManager.IMPORTANCE_DEFAULT;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel mChannel = new NotificationChannel(
                    channelId, channelName, importance);
            notificationManager.createNotificationChannel(mChannel);

            AudioAttributes audioAttributes = new AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
                    .build();

            mChannel.setSound(Uri.parse("android.resource://"+ context.getPackageName() + "/" + R.raw.cat), audioAttributes);




        }

        Bitmap largicon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic);
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, channelId)
                .setSmallIcon(R.drawable.ic_alarm)
                .setContentTitle("Ya es hora dormilon!")
                .setContentText(message)
                .setLargeIcon(largicon)
                //.setBadgeIconType(R.mipmap.ic_notification_round)
                .setCategory(NotificationCompat.CATEGORY_ALARM)
                .setSound(Uri.parse("android.resource://"+ context.getPackageName() + "/" + R.raw.cat))
                .setWhen(System.currentTimeMillis())
                .setPriority(importance)

                .setContentIntent(pendingIntent)
                .setAutoCancel(true)
                .setOnlyAlertOnce(true);


        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        stackBuilder.addNextIntent(intent);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
                0,
                PendingIntent.FLAG_UPDATE_CURRENT


        );

        //mBuilder.setContentIntent(pendingIntent);
        //mBuilder.setSound(soundUri, AudioManager.STREAM_ALARM);



        //vibrate
        long[] v = {500,1000};
        mBuilder.setVibrate(v);
        notificationManager.notify(notificationId, mBuilder.build());



    }

}

Answer:

The only thing you have to do is define the sound to be played in the NotificationCompat.Builder using the setSound() method.

Previously and now only for devices with API <= 26:

Add your sound file inside the / raw directory, assuming you added a mysound.mp3 file, this would be the way to load it:

mBuilder.setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.mysound));

But now for devices with API> 26, instead of "android.resource://" use ContentResolver.SCHEME_ANDROID_RESOURCE like this:

mBuilder.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE+ "://" + getPackageName() +"/"+R.raw.mysound))

Also remember that for this operating system you must define a channel and in this case add:

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

 AudioAttributes audioAttributes = new AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                    .build();

   mChannel.setSound(sound, audioAttributes); //* Esto configuraría el sonido custom.

There is something important, if the channel has already been created and its properties have been defined, you cannot make modifications, you will have to delete it and re-create it .

Scroll to Top