Android MediaPlayer – setDataSource und Release – IllegalStateException

Ich habe meine eigene MediaPlayer-Klasse geschrieben, um Dateien auf einem bestimmten Pfad abzuspielen und Dateien aus dem Assets-Ordner zu spielen. Hier ist die Klasse:

public class CMediaPlayer extends MediaPlayer{ public void play(String audioPath){ this.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); File f = new File(audioPath); if(f.exists()){ try{ FileInputStream fis = new FileInputStream(f); FileDescriptor fileD = fis.getFD(); this.setDataSource(fileD); this.prepare(); }catch(IOException e){ } this.start(); } } public void play(AssetFileDescriptor descriptor){ this.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); try { this.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength()); descriptor.close(); this.prepare(); }catch (IOException e){ } this.start(); } } 

Ich möchte mehrere Töne mit dieser Klasse aus einer Aktivität spielen. Hier ist mein Code:

  • Wie man .apk-Dateien in Java umwandelt
  • Keine Ressource gefunden, die mit dem Vornamen übereinstimmt: attr 'android: actionModeShareDrawable' appcompat-v7: 21.0.0 mit compileSdkVersion 21
  • Ist das Standardverhalten von Android WebView geändert, um intern alle Links zu öffnen?
  • Singleton in Android
  • Konvertieren Sie Xamarin.Forms.Color auf Plattform spezifische Farbe
  • Abbrechen SMS Intent auf Android KitKat
  •  public class playGame extends Activity { //a lot of variables CMediaPlayer mediaPlayer; //declare my mediaplayer @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK ) { //release?????? Intent myIntent = new Intent(getBaseContext(), startView.class); startActivity(myIntent); } return super.onKeyDown(keyCode, event); } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_play_question2); mediaPlayer = new CMediaPlayer(); //define my mediaplayer //stuff } //more variables public void playQuestion(File question){ //stuff TextView myTextView = (TextView) findViewById(R.id.textViewQuestion); //stuff myTextView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mediaPlayer.play(pathSoundQuestion); //play sound when clicked } }); //stuff myImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mediaPlayer.play(pathSoundQuestion); //play sound when clicked } }); //stuff mediaPlayer.play(pathSoundQuestion); //plays sound immediatly, first played sound (works fine) //button1 Button myButton = (Button) findViewById(R.id.button1); //stuff myButton.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { if(lastClickedButton == v){ //stuff return; } //stuff mediaPlayer.play(pathAudio1); //play sound when clicked (error) } }); //button2 myButton = (Button) findViewById(R.id.button2); //stuff myButton.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { if(lastClickedButton == v){ //stuff return; } //stuff mediaPlayer.play(pathAudio2); //play sound, same problem } }); //goes on like this some more times... } public void logIn(View v, String right){ //stuff if(right.equals("true")){ //stuff try { AssetFileDescriptor descriptor = getAssets().openFd("Right"); mediaPlayer.play(descriptor); //play sound from assets Intent myIntent = new Intent(getApplication(), playGame.class); startActivity(myIntent); }catch (IOException e){ } }else{ //stuff try { AssetFileDescriptor descriptor = getAssets().openFd("Wrong"); mediaPlayer.play(descriptor); //play sound from assets Intent myIntent = new Intent(getApplication(), playGame.class); startActivity(myIntent); }catch (IOException e){ } } } } 

    Die App spielt den ersten Ton, wie in meinen Kommentaren in meinem Code erwähnt. Wenn ich auf eine Schaltfläche klicke, die einen anderen Sound starten soll, bekomme ich folgende Fehlermeldung:

     03-16 23:07:38.478 13646-13646/com.example.cello.myownquiz E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.IllegalStateException at android.media.MediaPlayer.setDataSource(Native Method) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1005) 

    Ist meine MediaPlayer-Klasse okay oder vermisse ich je nach Zustand etwas? Ist diese Klasse der einzige Ort, um Freigabe zu nennen oder muss ich es irgendwo in meiner Tätigkeit auch setzen?

    Hat jemand meinen Fehler gesehen? Dieses Problem mit dem MediaPlayer hat mir einen ganzen Tag versucht, hoffe du kannst mir helfen …

  • Kann nicht statische Bezugnahme auf nicht-statische Methode (Android getApplicationContext ())
  • Android AsyncTaskLoader startet nicht loadInBackground?
  • Benutzerdefinierte Ansichten in der Symbolleiste wie Airbnb erkunden Bildschirm
  • Hat Android Widget wie das iPhone UIPickerView
  • Android-Fragment-Navigation für Tabletten - Einzel- oder Mehrfachaktivitäten?
  • MediaRecorder ist fehlgeschlagen, wenn ich die Aufnahme stoppe
  • 2 Solutions collect form web for “Android MediaPlayer – setDataSource und Release – IllegalStateException”

    mp.release(); Zu mp.reset();

    Public void reset ()

    Setzt den MediaPlayer auf seinen nicht initialisierten Zustand zurück. Nachdem Sie diese Methode aufgerufen haben, müssen Sie sie erneut initialisieren, indem Sie die Datenquelle einstellen und Vorbereitung () aufrufen.

    Public void release ()

    Gibt die mit diesem MediaPlayer-Objekt verknüpften Ressourcen frei. Es gilt als gute Praxis, diese Methode aufzurufen, wenn Sie mit dem MediaPlayer fertig sind. Insbesondere, wenn eine Aktivität einer Anwendung pausiert wird (ihre onPause () -Methode wird aufgerufen) oder gestoppt (ihre onStop () -Methode wird aufgerufen), sollte diese Methode aufgerufen werden, um das MediaPlayer-Objekt freizugeben, es sei denn, die Anwendung hat eine spezielle Muss das Objekt herumhalten . Zusätzlich zu unnötigen Ressourcen (z. B. Speicher und Instanzen von Codecs), die nicht sofort aufgerufen werden, wenn ein MediaPlayer-Objekt nicht mehr benötigt wird, kann es auch zu einem kontinuierlichen Batterieverbrauch für mobile Geräte und zum Wiedergabeschluss für andere Anwendungen kommen, wenn nein Mehrere Instanzen des gleichen Codecs werden auf einem Gerät unterstützt. Auch wenn mehrere Instanzen des gleichen Codecs unterstützt werden, kann eine gewisse Leistungsverschlechterung erwartet werden, wenn unnötige Mehrfachinstanzen gleichzeitig verwendet werden.

    Du musst das Objekt herumhalten.

    Irgendwie kannst du es auf einfache Weise machen

      MeddiaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(context, ringtone); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MEDIA); mediaPlayer.prepare(); mediaPlayer.start(); 

    Ich habe auch dieses Problem, aber ich habe verwendet:

     public void play(String name){ try { AssetFileDescriptor afd = getAssets().openFd(name); if(myPlayer == null){ myPlayer = new MediaPlayer(); } myPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); myPlayer.prepare(); myPlayer.start(); } catch (IOException e) { e.printStackTrace(); } } 

    Und zu stoppen

     public void stopPlayer(){ if(myPlayer!= null && myPlayer.isPlaying()){ myPlayer.stop(); myPlayer = null; }else{ myPlayer = null; } } 
    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.