Search code examples
androidnotifications

Set a custom sound in the local notification


Android 13

Create a local notification with a custom sound

I have my event_sound.mp3 in my res/raw/event_sound.mp3

I have the following notification

val notification = NotificationCompat.Builder(context, channelId)
    .setContentTitle(title)
    .setContentText(description)
    .setSmallIcon(R.drawable.bell)
    .setAutoCancel(true)
    .setContentIntent(pendingIntent)
    .setSound(getUriSoundFile(context))
    .build()

I have the following method to extract the sound file which is in my data module.

 private fun getUriSoundFile(context: Context): Uri {
        val uri = Uri.parse("android.resource://" + "me.androidbox.data" + "/raw/" + "event_sound.mp3")

        return uri
    }

When I check the full path I get the following:

android.resource://me.androidbox.data/raw/event_sound.mp3

I have set my channels in my Application class like this:

  private fun createNotificationChannel(listOfChannel: Map<String, String>) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            listOfChannel.map { mapOfChannel ->
                val notificationManager = getNotificationManager()
                val notificationChannel = NotificationChannel(
                    mapOfChannel.key,
                    mapOfChannel.value,
                    NotificationManager.IMPORTANCE_HIGH
                )

                notificationManager.createNotificationChannel(notificationChannel)
            }
        }
    }

However, the notification only sounds the default and never plays my custom sound.

UPDATE ====

I have the following in my Application class. The event_sound is in the following directly

raw/event_sound.mp3

And this is the debug output android.resource://me.androidbox.presentation/2131558400

This is my updated code:

private fun createNotificationChannel(listOfChannel: Map<String, String>) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        listOfChannel.map { mapOfChannel ->
            val notificationManager = getNotificationManager()
            val notificationChannel = NotificationChannel(
                mapOfChannel.key,
                mapOfChannel.value,
                NotificationManager.IMPORTANCE_HIGH
            )

            val audioAttributes = AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT)
                .build()

            notificationChannel.setSound(getUriSoundFile(), audioAttributes)
            notificationManager.createNotificationChannel(notificationChannel)
        }
    }
}

Solution

  • Problem Description : After Android 13 all notification sounds regardless of in app selection is set to default sound

    Make sure your notification sound is in mp3 format in res/raw.

    You can leave the else part as is.

    New Answer


    private fun getUriSoundFile(context: Context): Uri {
            val uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.packageName + "/" + R.raw.event_sound.mp3)
    
            return uri
        }
    
    
    private fun createNotificationChannel(listOfChannel: Map<String, String>) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            listOfChannel.map { mapOfChannel ->
                val notificationManager = getNotificationManager()
                val notificationChannel = NotificationChannel(
                    mapOfChannel.key,
                    mapOfChannel.value,
                    NotificationManager.IMPORTANCE_HIGH
                )
    
                val audioAttributes = AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                    .build()
    
                notificationChannel.setSound(getUriSoundFile(), audioAttributes)
                notificationManager.createNotificationChannel(notificationChannel)
            }
        }
    }
    

    Old Answer

    private fun createNotificationChannel() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    val audioAttributes = AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                        .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT)
                        .build()
        
                    val uri = Uri.parse("android.resource://$packageName/${R.raw.sample_sound}")
        
                    val channel = NotificationChannel(
                        CHANNEL_ID,
                        "Channel Name",
                        NotificationManager.IMPORTANCE_DEFAULT
                    ).apply {
                        description = "Description"
                        setSound(uri, audioAttributes)
                    }
                    val notificationManager =
                        getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                    notificationManager.createNotificationChannel(channel)
                }
            }