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.

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

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

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.


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.


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

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.


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


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

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.


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

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


-4

Aqui está um exemplo de código:

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.