Como reproduzir toque / som de alarme no Android

119

Tenho procurado em todos os lugares como reproduzir um som de toque / alarme no Android.

Eu pressiono um botão e quero reproduzir um toque / som de alarme. Não consegui encontrar uma amostra fácil e direta. Sim, já olhei o código-fonte do despertador ... mas não é simples e não consigo compilá-lo.

Eu não posso fazer isso funcionar:

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();
}

Eu recebo este erro:

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

Então ... por favor, se alguém souber como tocar um toque / alarme padrão, me avise.

Prefiro não fazer upload de nenhum arquivo. Basta tocar um toque padrão.

Federico
fonte

Respostas:

186

Você pode simplesmente reproduzir um toque definido com este:

Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
markov00
fonte
Ainda recebo um erro - Falha ao abrir o conteúdo do toque: // settings / system / alarm_alert
Desai
3
Bom e simples. No entanto, dependendo do dispositivo, esse método pode interromper outros sons (como música) que podem ser reproduzidos no Android.
igordc
Usar getApplicationContext () pode não ser uma opção muito boa. Mais informações aqui: stackoverflow.com/questions/9122627/…
Saket
@ BartSimpson como você resolveu o problema, também estou recebendo este erro
user3233280
1
O toque não pode ser interrompido. Se iniciar o toque novamente, toca o dobro. stopPrevious não está funcionando, a propósito, eu crio o tocador de ringtone com o mesmo objeto de contexto, não getapplicationcontext.
Metehan Toksoy
65

Se um usuário nunca definiu um alarme em seu telefone, o TYPE_ALARM pode retornar nulo. Você pode explicar isso com:

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
fonte
1
O URI retornado pode não ser null, embora não aponte para um som válido. Você deve testar o valor de retorno de RingtoneManager.getRingtone()para em nullvez de / também
Átila
Em 2017, não funcionou, não ligou. Está funcionando no Android recente?
55

Esta é a maneira que fiz:

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

É semelhante ao método do markov00, mas usa o MediaPlayer em vez do Ringtone, o que evita a interrupção de outros sons, como música, que já podem estar tocando no fundo.

igordc
fonte
5
Tentei a resposta principal (ringtone.play), mas o som pode ser cortado. Usei essa abordagem e funcionou perfeitamente.
wyz
1
Esta é a melhor solução para qualquer pessoa que use qualquer outro componente de áudio em seu aplicativo.
EntangledLoops
@YumYumYum, acabei de testar e funciona. Não fiz nada além de colocar o código acima em meu setOnClickListner. O que você fez?
apresentará céu
17

Seu exemplo é basicamente o que estou usando. Ele nunca funciona no emulador, entretanto, porque o emulador não tem nenhum toque de chamada por padrão e content://settings/system/ringtonenão se transforma em nada que possa ser reproduzido. Funciona bem no meu telefone real.

sínico
fonte
11

Isso funciona bem:

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
fonte
2
Por que você está dividindo o volume por 7,0? É um valor de trabalho comumente conhecido ou algo que você descobriu?
ErGo_404
Algo que descobri ...: D
Kamran Ahmed
Por que você faz Float.parseFloat (Double.toString (....)) ?? Passando por uma instância de String porque você deseja uma conversão double-> float? Por que você faz isso?
Zordid
1
Esta parte é Uri.parse redundante (RingtoneManager.getDefaultUri (RingtoneManager.TYPE_NOTIFICATION)), getDefaultUri () já retorna um URI, não há necessidade de analisá-lo ainda em outro URI
DritanX
1
7 é um volume máximo para o stram
Leo Droidcoder
11

Para os futuros googlers: use em RingtoneManager.getActualDefaultRingtoneUri()vez de RingtoneManager.getDefaultUri(). De acordo com seu nome, ele retornaria o uri real, para que você possa usá-lo livremente. Da documentação de getActualDefaultRingtoneUri():

Obtém o Uri do som padrão atual. Isso fornecerá o som Uri real ; em vez de usá-lo, a maioria dos clientes pode usar DEFAULT_RINGTONE_URI.

Enquanto isso, getDefaultUri()diz o seguinte:

Retorna o Uri para o toque padrão de um tipo específico. Em vez de retornar o Uri do som do toque real, isso retornará o Uri simbólico, que será resolvido para o som real quando reproduzido.

Matvey Rybakov
fonte
9

Você pode enviar um arquivo MP3 para a pasta / sdcard usando DDMS, reiniciar o emulador, abrir o aplicativo de mídia, navegar até o arquivo MP3, pressioná-lo e selecionar "Usar como toque do telefone".

O erro desapareceu!

Editar: mesmo problema com sons de notificação (por exemplo, para SMS) resolvido usando o aplicativo Ringdroid

OcuS
fonte
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 ensolarado
fonte
de onde AlarmServicevem?
Eduardo Wada
2

Copiar um arquivo de áudio para o cartão SD do emulador e selecioná-lo por meio do reprodutor de mídia como o toque padrão realmente resolve o problema.

Valentin Klinghammer
fonte
2

Você pode usar este código de amostra:

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

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

Pode ser tarde, mas há uma nova solução simples para essa questão para quem quiser.
Em kotlin

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

O código acima irá tocar o toque padrão, mas se você quiser o alarme padrão, mude

Settings.System.DEFAULT_RINGTONE_URI

para

Settings.System.DEFAULT_ALARM_ALERT_URI

Reza
fonte
-4

Aqui está um exemplo de código:

Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), notification);
mediaPlayer.start();
Nishant
fonte
Explique o código com um pouco de explicação, respostas apenas do código não são apreciadas.
Sulthan Allaudeen
Qual é cara, você nunca leu as respostas acima provavelmente. stackoverflow.com/a/20177743/3332634
yshahak
1
Isso é basicamente idêntico a esta resposta , mas com o nome da variável em mediaPlayervez de mp.
Makyen