1

I'm trying to send an alarm like notification that stays on the screen and plays the alarm sound until it's closed.

I tried setting the alarm sound on the notification channel and on the notification itself but nothing seems to work, the notification always plays the default notification sound.

val name = "name"
        val descriptionText = "desc"
        val importance = NotificationManager.IMPORTANCE_HIGH
        val channel = NotificationChannel("id", name, importance).apply {
            description = descriptionText
        }


        val notificationManager: NotificationManager =
            context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)


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

        channel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE), audioAttributes)

        val builder = NotificationCompat.Builder(context, "id")
            .setSmallIcon(R.drawable.ic_android_black_24dp)
            .setContentTitle("textTitle")
            .setContentText("textContent")
            .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM))
            .setPriority(NotificationCompat.PRIORITY_MAX)
            //.setCategory(NotificationCompat.CATEGORY_ALARM)
            .setFullScreenIntent(fullScreenPendingIntent, true)
            .addAction(1, "a", closeButtonPendingIntent)



        with(NotificationManagerCompat.from(context)) {
            notify(0, builder.build())
        }
Richard Onslow Roper
  • 5,477
  • 2
  • 11
  • 42
Martim Gouveia
  • 81
  • 1
  • 2
  • 5

1 Answers1

1

There's no way to make the notification "sound" like the alarm that will satisfy your use-case. You could use the RingtoneManager API to retrieve the default alarm sound, and use the setSound method of the "builder" (not the notification channel) to notify with that sound, but even then, it will be just one iteration of a short sound sequence, then it'll stop. Notifications Builders are not meant to be used for playing a constant sound for the user. They are just single-shot notifications.

For an alarms app, you'll need a MediaPlayer alongside the notification builder. You'd likely want to keep the notification itself silent, and use the sound retrieved from the RingtoneManager to make a sound using the mediaplayer instance with isLooping set to true.

The ringtones cannot be expected to last indefinitely. They are short sequences of sound. You are the one who has to play it until it needs to be stopped.

Sample implementation:

MediaPlayer().apply {
  dataSource = /*Add Default Ringtone here*/
  isLooping = true
  start()
}
Richard Onslow Roper
  • 5,477
  • 2
  • 11
  • 42
  • Thank you for the help! I understood why my approach wasn't the right one and most of the solution but I didn't understand a detail. I understood what the code you wrote does but where should i put it so it runs with the notification? Currently the notification is sent with an intent but the activity in it only "runs" when the notification is clicked. Is there a way to play the sound when the notification appears and stop playing when it is closed? – Martim Gouveia Sep 04 '22 at 21:34
  • Where are you creating the builder? Doesn't matter. Just paste the code alongside the builder, hold the `start` call. The moment you call the notification's `notify`, add the `start` in an `also` block. Then, to stop the player, you can have a broadcast receiver registered in this same class. Have the register listening on a custom intent action. Whenever you need to stop the sound, i.e., from an Activity or wherever in the OS, just broadcast an Intent with the said action, and your receiver will be triggered. Call to `player.stop()` and dispose in the `onReceive` of the receiver at call site – Richard Onslow Roper Sep 04 '22 at 22:37
  • Building an alarms app yeah? Same here. Care to join an internal testing program? – Richard Onslow Roper Sep 04 '22 at 22:41
  • It's not only an alarms app but it also uses alarms. Can you explain what that is? I'm not really used to it. Would it help in things like this? – Martim Gouveia Sep 05 '22 at 16:44
  • You couldn't grab the concept of a `BroadcastReceiver`? Just Google how to register one programmatically to listen for a custom intent. It is fairly simple. If you still don't get it, comment back here. You didn't answer the internal testing program question. – Richard Onslow Roper Sep 06 '22 at 01:45
  • No i understood the answer and it is already working, I was asking about the internal testing program – Martim Gouveia Sep 11 '22 at 02:29
  • Oh ok. If the problem is resolved, accept the answer. The internal testing program is just a custom testing program for my specific app. As in, before launching it to production, I give certain people access to it, to gain internal feedback. You won't have access to any code, but you'll be just like a user who will test the app for its functionality. I'll need to add you to the list in of internal testers, so I'll need your email, but don't post it here publicly. If you are in, I'll create a separate room so you can share it securely. – Richard Onslow Roper Sep 11 '22 at 03:45