Riproduci il suono al clic del pulsante Android


109

Come faccio a ottenere un pulsante per riprodurre un suono da raw quando faccio clic? Ho appena creato un pulsante con id button1, ma qualunque sia il codice che scrivo, è tutto sbagliato.

import android.media.MediaPlayer;

public class BasicScreenActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_basic_screen);
    }

    Button one = (Button)this.findViewById(R.id.button1);
    MediaPlayer = mp;
    mp = MediaPlayer.create(this, R.raw.soho);
    zero.setOnCliclListener(new View.OnClickListener() )

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.basic_screen, menu);
        return true;
    }



}

1
Probabilmente vorresti che le risorse fossero gestite automaticamente, in modo da poter chiamare MusicManager.getInstance().play(this, R.raw.my_sound);. Se è così, questa libreria potrebbe fare al caso tuo: github.com/delight-im/Android-Audio
caw

Risposte:


228

Questa è la parte più importante del codice fornito nel post originale.

Button one = (Button) this.findViewById(R.id.button1);
final MediaPlayer mp = MediaPlayer.create(this, R.raw.soho);
one.setOnClickListener(new OnClickListener(){

    public void onClick(View v) {
        mp.start();
    }
});

Per spiegarlo passo dopo passo:

Button one = (Button) this.findViewById(R.id.button1);

La prima è l'inizializzazione del pulsante da utilizzare per riprodurre il suono. Usiamo l'attività findViewById, passando l'ID che gli abbiamo assegnato (nel caso di questo esempio :) R.id.button1, per ottenere il pulsante di cui abbiamo bisogno. Lo creiamo come a in Buttonmodo che sia facile assegnarlo alla variabile oneche stiamo inizializzando. Spiegare di più su come funziona è fuori portata per questa risposta. Questo fornisce una breve panoramica su come funziona.

final MediaPlayer mp = MediaPlayer.create(this, R.raw.soho);

Ecco come inizializzare un file MediaPlayer. MediaPlayer segue lo Static Factory Method Design Pattern . Per ottenere un'istanza, chiamiamo il suo create()metodo e gli passiamo il contesto e l'ID risorsa del suono che vogliamo riprodurre, in questo caso R.raw.soho. Lo dichiariamo come final. Jon Skeet ha fornito un'ottima spiegazione del motivo per cui lo facciamo qui .

one.setOnClickListener(new OnClickListener(){

    public void onClick(View v) {
        //code
    }
});

Infine, impostiamo cosa farà il nostro pulsante precedentemente inizializzato. Riproduci un suono al clic del pulsante! Per fare ciò, impostiamo il OnClickListenerdel nostro pulsante one. All'interno c'è solo un metodo, onClick()che contiene le istruzioni che il pulsante deve eseguire al clic .

public void onClick(View v) {
    mp.start();
}

Per riprodurre il suono, chiamiamo il start()metodo di MediaPlayer . Questo metodo avvia la riproduzione del suono.

Lì, ora puoi riprodurre un suono al clic del pulsante in Android!


Parte bonus:

Come notato nel commento qui sotto Grazie Langusten Gustel! e, come consigliato nella guida di riferimento per gli sviluppatori Android , è importante chiamare il release()metodo per liberare risorse che non verranno più utilizzate. Di solito, questo viene fatto una volta che il suono da riprodurre ha completato la riproduzione. Per fare ciò, aggiungiamo un OnCompletionListeneral nostro mp simile così:

mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {
        //code
    }
});

All'interno del onCompletionmetodo, lo rilasciamo in questo modo:

public void onCompletion(MediaPlayer mp) {
    mp.release();
}

Ovviamente ci sono modi migliori per implementarlo . Ad esempio, puoi rendere MediaPlayer una variabile di classe e gestirne il ciclo di vita insieme al ciclo di vita di Fragmento Activityche lo utilizza. Tuttavia, questo è un argomento per un'altra domanda. Per mantenere piccolo lo scopo di questa risposta, l'ho scritta solo per illustrare come riprodurre un suono al clic del pulsante in Android .


Post originale

Primo. Dovresti mettere le tue dichiarazioni all'interno di un blocco, e in questo caso il metodo onCreate.

Secondo. Hai inizializzato il pulsante come variabile uno , quindi hai usato una variabile zero e hai impostato il suo onClickListener su un onClickListener incompleto. Utilizzare la variabile uno per il setOnClickListener.

Terzo, inserisci la logica per riprodurre il suono all'interno di onClick.

In sintesi:

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class BasicScreenActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_basic_screen);

        Button one = (Button)this.findViewById(R.id.button1);
        final MediaPlayer mp = MediaPlayer.create(this, R.raw.soho);
        one.setOnClickListener(new OnClickListener(){

            public void onClick(View v) {
                mp.start();
            }
        });
    }
}

1
E tra l'altro è one.setOnClickListener (new View.OnClickListener () {public void onClick (View v) {mp.start ();}}); Da non perdere!
Auto-Droid ツ

7
non per arrivare aRELEASE
Langusten Gustel

38

Testato e funzionante al 100%

public class MainActivity extends ActionBarActivity {
    Context context = this;
    MediaPlayer mp;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);
        mp = MediaPlayer.create(context, R.raw.sound);
        final Button b = (Button) findViewById(R.id.Button);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                try {
                    if (mp.isPlaying()) {
                        mp.stop();
                        mp.release();
                        mp = MediaPlayer.create(context, R.raw.sound);
                    } mp.start();
                } catch(Exception e) { e.printStackTrace(); }
            }
        });
    }
}

Questo era tutto quello che dovevamo fare

if (mp.isPlaying()) {
    mp.stop();
    mp.release();
    mp = MediaPlayer.create(context, R.raw.sound);
}

Funziona anche durante la riproduzione dell'audio. Quando si riproduce il suono, penso che mp.start () funzionerà senza i blocchi try / catch e if.
khwilo

37

Il modo migliore per farlo è qui che ho trovato dopo aver cercato un problema dopo l'altro in LogCat

MediaPlayer mp;
mp = MediaPlayer.create(context, R.raw.sound_one);
mp.setOnCompletionListener(new OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) {
        // TODO Auto-generated method stub
        mp.reset();
        mp.release();
        mp=null;
    }
});
mp.start();

Non mancato rilascio del lettore multimediale ti dà questo errore in LogCat:

Android: MediaPlayer è stato finalizzato senza essere rilasciato

Non resettare mancato del lettore multimediale ti dà questo errore in LogCat:

Android: mediaplayer è andato via con eventi non gestiti

Quindi gioca un codice semplice e sicuro per utilizzare il lettore multimediale.

Per riprodurre più di un suono nella stessa attività / frammento è sufficiente modificare il resID durante la creazione di un nuovo lettore multimediale simile

mp = MediaPlayer.create(context, R.raw.sound_two);

e suonalo!

Divertiti!


8
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {
    MediaPlayer mp;
    Button one;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mp = MediaPlayer.create(this, R.raw.soho);
        one = (Button)this.findViewById(R.id.button1);

        one.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                mp.start();
            }
        });
    }
}

Ecco il risultato, ancora una volta niente funziona dropbox.com/s/9xb0lzesp0ibx9z/2.jpg
Dmitry

Non hai bisogno della riga mp = new MediaPlayer () perché lo stai inizializzando di nuovo usando MediaPlayer.create (...) nella riga successiva.
Keale

6
  • L'audio deve essere posizionato nel file raw cartella, se non esiste crearne uno.
  • La cartella raw deve essere all'interno della cartella res
  • Il nome non deve contenere -caratteri speciali o nessuno .

Sulla tua attività, devi avere un oggetto MediaPlayer, all'interno del onCreatemetodo o del onclickmetodo, devi inizializzare il MediaPlayer, mi piace MediaPlayer.create(this, R.raw.name_of_your_audio_file), quindi il tuo file audio è pronto per essere riprodotto con la chiamata start(), nel tuo caso, dato che vuoi che sia posto in un pulsante, dovrai inserirlo nel onClickmetodo.

Esempio:

private Button myButton;
private MediaPlayer mp;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.myactivity);
        mp = MediaPlayer.create(this, R.raw.gunshot);

        myButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mp.start();
            }
        });
}
}

3

ci sono alcuni suoni predefiniti: SHUTTER_CLICK, FOCUS_COMPLETE, START_VIDEO_RECORDING, STOP_VIDEO_RECORDING.

Bello!

MediaActionSound

Una classe per la produzione di suoni che corrispondono a quelli prodotti da varie azioni intraprese dai media e dalle API della fotocamera. Documenti

usa come:

fun playBeepSound() {
    val sound = MediaActionSound()
    sound.play(MediaActionSound.START_VIDEO_RECORDING)
}

2
Button button1=(Button)findViewById(R.id.btnB1);
button1.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
MediaPlayer mp1 = MediaPlayer.create(this, R.raw.b1);
mp1.start();
}
});

Prova questo, penso che funzionerà


1
public class MainActivity extends AppCompatActivity {

    public void clickMe (View view) {

        MediaPlayer mp = MediaPlayer.create(this, R.raw.xxx);
        mp.start();

    }

creare un pulsante con un metodo può essere chiamato quando il pulsante viene premuto (onCreate),

quindi crea una variabile per la classe (MediaPlayer) con il percorso del tuo file

MediaPlayer mp = MediaPlayer.create(this, R.raw.xxx);

infine eseguire il metodo di avvio in quella classe

mp.start();

il file verrà eseguito quando il pulsante viene premuto, spero che sia stato utile!


3
Benvenuto in Stack Overflow! Sarebbe meglio se aggiungi alcune spiegazioni e commenti al tuo codice in modo che i futuri lettori possano imparare da te.
Mehdi Bounya

1

Invece di resettarlo come proposto da DeathRs:

if (mp.isPlaying()) {
       mp.stop();
       mp.release();
       mp = MediaPlayer.create(context, R.raw.sound);
} mp.start();

possiamo semplicemente ripristinare il MediaPlayer per iniziare a utilizzare:

if (mp.isPlaying()) {
       mp.seekTo(0)
}

1

Tutte queste soluzioni "suonano" belle e ragionevoli, ma c'è un grande svantaggio. Cosa succede se il cliente scarica la tua applicazione e preme ripetutamente il tuo pulsante?

Il tuo MediaPlayer volte non riuscirai a riprodurre il suono se fai clic sul pulsante molte volte.

Mi sono imbattuto in questo problema di prestazioni con la MediaPlayerclasse pochi giorni fa.

La MediaPlayerclasse è salvata per essere utilizzata? Non sempre. Se hai suoni brevi è meglio usare la SoundPoolclasse.

Una soluzione sicura ed efficiente è la classe SoundPool che offre grandi funzionalità e aumenta le prestazioni della tua applicazione.

SoundPool non è facile da usare come il MediaPlayer classe, ma offre alcuni grandi vantaggi in termini di prestazioni e affidabilità.

Segui questo collegamento e scopri come utilizzare la classe SoundPool nella tua applicazione:

https://developer.android.com/reference/android/media/SoundPool

Youtube: salva la soluzione


0

Un caso limite: sopra ogni risposta è quasi corretto, ma sono rimasto bloccato in un caso limite. Se un utente fa clic in modo casuale più volte sul pulsante in pochi secondi, dopo aver riprodotto un suono non risponde più.

Motivo: l' inizializzazione Mediaplayerdell'oggetto è molto costosa. Si occupa anche delle risorse ( file audio ), quindi ci vuole un po 'di tempo. Quando gli utenti in modo casuale inizializzazione e chiamando un metodo di MediaPlayermetodi 's come start(), stop(), release(), ecc possono causare IllegalStateException, che ho affrontato.

Soluzione: Grazie caw per il suo suggerimento nel commento su Android-Audio . Ha solo due semplici classi java ( MusicManager.java, SoundManager.java).

Puoi usare MusicManager.javase vuoi riprodurre file audio una tantum -

MusicManager.getInstance().play(MyActivity.this, R.raw.my_sound);

Puoi usare SoundManager.javase vuoi riprodurre più suoni frequentemente e velocemente -

class MyActivity extends Activity {

    private SoundManager mSoundManager;

    @Override
    protected void onResume() {
        super.onResume();

        int maxSimultaneousStreams = 3;
        mSoundManager = new SoundManager(this, maxSimultaneousStreams);
        mSoundManager.start();
        mSoundManager.load(R.raw.my_sound_1);
        mSoundManager.load(R.raw.my_sound_2);
        mSoundManager.load(R.raw.my_sound_3);
    }

    private void playSomeSound() {
        if (mSoundManager != null) {
            mSoundManager.play(R.raw.my_sound_2);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mSoundManager != null) {
            mSoundManager.cancel();
            mSoundManager = null;
        }
    }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.