Cómo reproducir tono de llamada / sonido de alarma en Android

119

He estado buscando en todas partes cómo reproducir un tono de llamada / sonido de alarma en Android.

Presiono un botón y quiero reproducir un tono de llamada / sonido de alarma. No pude encontrar una muestra sencilla y directa. Sí, ya miré el código fuente del despertador ... pero no es sencillo y no puedo compilarlo.

No puedo hacer que esto funcione:

Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM); 
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(this, alert);
final AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);

if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
    player.setAudioStreamType(AudioManager.STREAM_ALARM);
    player.setLooping(true);
    player.prepare();
    player.start();
}

Me sale este error:

04-11 17:15:27.638: ERROR/MediaPlayerService(30): Couldn't open fd for
content://settings/system/ringtone

Entonces ... por favor, si alguien sabe cómo reproducir un tono de llamada / alarma predeterminado, hágamelo saber.

Prefiero no subir ningún archivo. Simplemente reproduce un tono de llamada predeterminado.

Federico
fuente

Respuestas:

186

Simplemente puede reproducir un tono de llamada establecido con esto:

Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
markov00
fuente
Sigo recibiendo un error - No se pudo abrir el contenido del tono de llamada: // settings / system / alarm_alert
Pritesh Desai
3
Agradable y sencillo. Sin embargo, según el dispositivo, este método puede interrumpir otros sonidos (como música) que se estén reproduciendo en Android.
igordc
Usar getApplicationContext () podría no ser una muy buena opción. Más información aquí: stackoverflow.com/questions/9122627/…
Saket
@BartSimpson cómo resolvió el problema, también recibo este error
user3233280
1
El tono de llamada no se puede detener. Si vuelve a empezar el tono de llamada, se reproduce el doble. stopPrevious no funciona, por cierto creo un reproductor de tono de llamada con el mismo objeto de contexto, no getapplicationcontext.
Metehan Toksoy
65

Si un usuario nunca ha configurado una alarma en su teléfono, TYPE_ALARM puede devolver un valor nulo. Puede dar cuenta de esto con:

Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);

if(alert == null){
    // alert is null, using backup
    alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

    // I can't see this ever being null (as always have a default notification)
    // but just incase
    if(alert == null) {  
        // alert backup is null, using 2nd backup
        alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);                
    }
}
Blundell
fuente
1
Es posible que el URI devuelto no sea nullasí aunque no apunte a un sonido válido. Debería probar el valor de retorno de RingtoneManager.getRingtone()for en su nulllugar / también
Attila
En 2017, no funciona sin sonar. ¿Lo tienes funcionando en Android reciente?
55

Esta es la forma en que lo he hecho:

Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), notification);
mp.start();

Es similar a la forma de markov00, pero usa MediaPlayer en lugar de Ringtone, lo que evita la interrupción de otros sonidos, como la música, que puede que ya se estén reproduciendo de fondo.

igordc
fuente
5
Probé la respuesta principal (ringtone.play) pero el sonido puede cortarse. Usé este enfoque y funcionó a la perfección.
wyz
1
Esta es una mejor solución para cualquiera que use cualquier otro componente de audio en su aplicación.
EntangledLoops
@YumYumYum, acabo de probar y funciona. No hice nada más que poner el código anterior en mi setOnClickListner. ¿Qué hiciste?
Feature Sky
17

Tu ejemplo es básicamente lo que estoy usando. Sin embargo, nunca funciona en el emulador porque el emulador no tiene ningún tono de llamada predeterminado y content://settings/system/ringtoneno se resuelve en nada reproducible. Funciona bien en mi teléfono real.

synic
fuente
11

Esto funciona bien:

AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
MediaPlayer thePlayer = MediaPlayer.create(getApplicationContext(), RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));

try {
    thePlayer.setVolume((float) (audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION) / 7.0)),
                        (float) (audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION) / 7.0)));
} catch (Exception e) {
    e.printStackTrace();
}

thePlayer.start();
Kamran Ahmed
fuente
2
¿Por qué estás dividiendo el volumen entre 7.0? ¿Es un valor de trabajo comúnmente conocido o algo que usted mismo averigua?
ErGo_404
Algo que desenterré ...: D
Kamran Ahmed
¿Por qué haces Float.parseFloat (Double.toString (....)) ?? ¿Está pasando por una instancia de String porque desea una conversión doble-> flotante? ¿Por qué haces esto?
Zordid
1
Esta parte es Uri.parse redundante (RingtoneManager.getDefaultUri (RingtoneManager.TYPE_NOTIFICATION)), getDefaultUri () ya devuelve un URI, no es necesario analizarlo aún en otro URI
DritanX
1
7 es un volumen máximo para el stram
Leo Droidcoder
11

Para los futuros googlers: use en RingtoneManager.getActualDefaultRingtoneUri()lugar de RingtoneManager.getDefaultUri(). Según su nombre, devolvería el uri real, por lo que puede usarlo libremente. De documentación de getActualDefaultRingtoneUri():

Obtiene el Uri del sonido predeterminado actual. Esto dará el sonido Uri real , en lugar de usar esto, la mayoría de los clientes pueden usar DEFAULT_RINGTONE_URI.

Mientras tanto getDefaultUri()dice esto:

Devuelve el Uri para el tono de llamada predeterminado de un tipo en particular. En lugar de devolver el sonido Uri del tono de llamada real, esto devolverá el Uri simbólico que se resolverá con el sonido real cuando se reproduzca.

Matvey Rybakov
fuente
9

Puede insertar un archivo MP3 en su carpeta / sdcard usando DDMS, reiniciar el emulador, luego abrir la aplicación de Medios, buscar su archivo MP3, mantener presionado y seleccionar "Usar como tono de llamada del teléfono".

¡El error se ha ido!

Editar: el mismo problema con los sonidos de notificación (por ejemplo, para SMS) resuelto usando la aplicación Ringdroid

OcuS
fuente
4
public class AlarmReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(final Context context, Intent intent) {
        //this will update the UI with message
        Reminder inst = Reminder.instance();
        inst.setAlarmText("");

        //this will sound the alarm tone
        //this will sound the alarm once, if you wish to
        //raise alarm in loop continuously then use MediaPlayer and setLooping(true)
        Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        if (alarmUri == null) {
            alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
        }
        Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
        ringtone.play();

        //this will send a notification message
        ComponentName comp = new ComponentName(context.getPackageName(),
                AlarmService.class.getName());
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
    }
}
Kumar soleado
fuente
de donde AlarmServiceviene
Eduardo Wada
2

Copiar un archivo de audio en la tarjeta SD del emulador y seleccionarlo a través del reproductor multimedia como tono de llamada predeterminado resuelve el problema.

Valentin Klinghammer
fuente
2

Puede usar este código de muestra:

Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
Ringtone ringtoneSound = RingtoneManager.getRingtone(getApplicationContext(), ringtoneUri)

if (ringtoneSound != null) {
    ringtoneSound.play();
}
Gio MV
fuente
0

Puede que sea tarde, pero hay una nueva y sencilla solución a esta pregunta para quien la quiera.
En kotlin

val player = MediaPlayer.create(this,Settings.System.DEFAULT_RINGTONE_URI)
player.start()

El código anterior reproducirá el tono de llamada predeterminado, pero si desea una alarma predeterminada, cámbiela

Settings.System.DEFAULT_RINGTONE_URI

a

Settings.System.DEFAULT_ALARM_ALERT_URI

Reza
fuente
-4

Aquí hay un código de muestra:

Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), notification);
mediaPlayer.start();
Nishant
fuente
Explique el código con una pequeña explicación, no se agradecen las respuestas de solo código.
Sulthan Allaudeen
Vamos hombre, probablemente nunca hayas leído las respuestas anteriores. stackoverflow.com/a/20177743/3332634
yshahak
1
Esto es básicamente idéntico a esta respuesta , pero con el nombre de la variable en mediaPlayerlugar de mp.
Makyen