190

I was wondering how I could play a notification sound without playing it over the media stream. Right now I can do this via the media player, however I don't want it to play as a media file, I want it to play as a notification or alert or ringtone. heres an example of what my code looks like right now:

MediaPlayer mp = new MediaPlayer();
mp.reset();
mp.setDataSource(notificationsPath+ (String) apptSounds.getSelectedItem());
mp.prepare();
mp.start();
rptwsthi
  • 10,094
  • 10
  • 68
  • 109
ninjasense
  • 13,756
  • 19
  • 75
  • 92

10 Answers10

471

If anyone's still looking for a solution to this, I found an answer at How to play ringtone/alarm sound in Android

try {
    Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
    r.play();
} catch (Exception e) {
    e.printStackTrace();
}

You can change TYPE_NOTIFICATION to TYPE_ALARM, but you'll want to keep track of your Ringtone r in order to stop playing it... say, when the user clicks a button or something.

Community
  • 1
  • 1
Phidius
  • 5,197
  • 1
  • 17
  • 12
  • 2
    Motorola phones for example extended the preferences activity and allows the user to define a notification sound for sms and other categories. The above method will not work with this type of phones. Do you have any idea how to solve this issue? – David Feb 04 '13 at 09:39
  • 2
    I got an error with this: `MediaPlayer - Should have subtitle controller already set`. What does it mean? – Deqing May 11 '14 at 11:20
  • Using this solution, after 28/29 times, the sounds stops playing. Anyone knows why? – Tom Bevelander Oct 05 '16 at 14:22
  • 1
    Why do you catch every exception? Which one may be thrown? – Miha_x64 May 15 '17 at 14:23
  • 1
    I got `Couldn't open content://settings/system/notification_sound_cache: java.io.FileNotFoundException` error. i have resolve this with `Uri notification = RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_NOTIFICATION);` Here i have used `getActualDefaultRingtoneUri` instead of `getDefaultUri`. – Dhaval Patel Jun 13 '17 at 11:27
  • @TomBrinkkemper hi Tom, have you managed to solve that problem with no longer working after playing for 28/29 times? – Sam Oct 24 '17 at 07:32
  • 2
    @Sam, Yes. https://stackoverflow.com/q/39876885/2614353.Basicly, don't create a RingTone object everytime you play it. Create it once, and then play the same object multiple times. – Tom Bevelander Oct 24 '17 at 12:32
208

You can now do this by including the sound when building a notification rather than calling the sound separately.

//Define Notification Manager
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

//Define sound URI
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext())
        .setSmallIcon(icon)
        .setContentTitle(title)
        .setContentText(message)
        .setSound(soundUri); //This sets the sound to play

//Display notification
notificationManager.notify(0, mBuilder.build());
Rob Riddle
  • 3,544
  • 2
  • 18
  • 26
  • 13
    This solves a different problem - not "how to play a notification sound", but "how to play a notification *and* display a sound". The accepted answer is justified in its solution. – Fabian Tamp Apr 02 '14 at 02:34
  • 7
    Perhaps you should also set this to play through STREAM_NOTIFICATION so it is played with the OS current notification volume preference: .setSound(soundUri, AudioManager.STREAM_NOTIFICATION) – mwk Aug 04 '14 at 13:49
  • @Rob Riddle It is working fine. but in case of multiple notifications e.g. 100 notifications parallel the sound get mixed with next notification sound. logically if sound is already playing it should wait for completion of previous play. Can you please help in this scenario? – Waqas Ali Razzaq Jan 27 '17 at 08:54
  • not playing the sound when the app is in the background. any suggestion? – Sagar Nayak Mar 28 '18 at 07:04
50

If you want a default notification sound to be played, then you can use setDefaults(int) method of NotificationCompat.Builder class:

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(someText)
                .setDefaults(Notification.DEFAULT_SOUND)
                .setAutoCancel(true);

I believe that's the easiest way to accomplish your task.

aga
  • 27,954
  • 13
  • 86
  • 121
20

Try this:

public void ringtone(){
    try {
        Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
        r.play();
     } catch (Exception e) {
         e.printStackTrace();
     }
}
Melquiades
  • 8,496
  • 1
  • 31
  • 46
Ragu
  • 233
  • 2
  • 6
9

It's been a while since your question, but ... Have you tried setting the Audio stream type?

mp.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);

It must be done before prepare.

copolii
  • 14,208
  • 10
  • 51
  • 80
2
Intent intent = new Intent(this, MembersLocation.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra("type",type);
    intent.putExtra("sender",sender);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    String channelId = getString(R.string.default_notification_channel_id);

    Uri Emergency_sound_uri=Uri.parse("android.resource://"+getPackageName()+"/raw/emergency_sound");
   // Uri Default_Sound_uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    if(type.equals("emergency"))
    {
        playSound=Emergency_sound_uri;
    }
    else
    {
        playSound= Settings.System.DEFAULT_NOTIFICATION_URI;
    }

    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this, channelId)
                    .setSmallIcon(R.drawable.ic_notification)
                    .setContentTitle(title)
                    .setContentText(body)
                    .setSound(playSound, AudioManager.STREAM_NOTIFICATION)
                    .setAutoCancel(true)
                    .setColor(getColor(R.color.dark_red))
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setContentIntent(pendingIntent);

   // notificationBuilder.setOngoing(true);//for Android notification swipe delete disabling...

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

    // Since android Oreo notification channel is needed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(channelId,
                "Channel human readable title",
                NotificationManager.IMPORTANCE_HIGH);
        AudioAttributes att = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                .build();
        channel.setSound(Emergency_sound_uri, att);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(channel);
        }
    }

    if (notificationManager != null) {
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}
dsc clg
  • 31
  • 4
  • 1
    Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation](https://meta.stackexchange.com/q/114762/349538) would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you’ve made. – NOhs Mar 15 '18 at 13:17
2

I had pretty much the same question. After some research, I think that if you want to play the default system "notification sound", you pretty much have to display a notification and tell it to use the default sound. And there's something to be said for the argument in some of the other answers that if you're playing a notification sound, you should be presenting some notification message as well.

However, a little tweaking of the notification API and you can get close to what you want. You can display a blank notification and then remove it automatically after a few seconds. I think this will work for me; maybe it will work for you.

I've created a set of convenience methods in com.globalmentor.android.app.Notifications.java which allow you create a notification sound like this:

Notifications.notify(this);

The LED will also flash and, if you have vibrate permission, a vibration will occur. Yes, a notification icon will appear in the notification bar but will disappear after a few seconds.

At this point you may realize that, since the notification will go away anyway, you might as well have a scrolling ticker message in the notification bar; you can do that like this:

Notifications.notify(this, 5000, "This text will go away after five seconds.");

There are many other convenience methods in this class. You can download the whole library from its Subversion repository and build it with Maven. It depends on the globalmentor-core library, which can also be built and installed with Maven.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Garret Wilson
  • 18,219
  • 30
  • 144
  • 272
  • That's way to complicated to simply play a sound. You could just do this: http://stackoverflow.com/a/9622040/1417267 – slinden77 Jun 25 '12 at 20:46
1

I think the concept of "notification sound" is someway wrong for Android UI.

The Android expected behaviour is to use the standard Notification to alert the user. If you play a notification sound without the status bar icon, you get the user confused ("what was that sound? there is no icon here, maybe I have hearing problems?").

How to set sound on a notification is, for example, here: Setting sound for notification

Community
  • 1
  • 1
think01
  • 681
  • 1
  • 10
  • 22
  • 1
    Not really, this may be an in-app notification. For example if you're in a chat app and have small sound effects for incoming and outgoing messages. Those are notifications in essence and you want them to shut up when the phone is in silent mode. – copolii Sep 14 '11 at 19:19
  • Well, you're right but that's another thing. I was talking (assuming this was the question's topic) of "system notification sounds", that is on the system Android GUI. Of course, when you're into your own app, as all up to you. – think01 Sep 16 '11 at 14:42
0

You can use Notification and NotificationManager to display the notification you want. You can then customize the sound you want to play with your notification.

Valentin Rocher
  • 11,667
  • 45
  • 59
0

Set sound to notification channel

        Uri alarmUri = Uri.fromFile(new File(<path>));

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

        channel.setSound(alarmUri, attributes);
Milind Chaudhary
  • 1,632
  • 1
  • 17
  • 16