2013-07-18 5 views
9

Ho esaminato vari siti Web alla ricerca di una soluzione per questo problema nel mio codice. È un riproduttore audio di base con 3 pulsanti: riproduzione, pausa e stop. Riproduzione e pausa di lavoro ok e così si ferma ma una volta che l'audio è stato fermato si rifiuta di ricominciare da capo, gettando un errore:Errore MediaPlayer Android (-38, 0) "stop chiamato nello stato 0"

E/MediaPlayer: stop called in state 0 
E/MediaPlayer: error (-38, 0) 
E/MediaPlayer: Error (-38,0) 

Questo è il mio MainActivity.java:

import android.app.Activity; 
import android.media.MediaPlayer; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Handler; 
import android.view.Menu; 
import android.view.View; 
import android.widget.Button; 
import android.widget.SeekBar; 

import java.io.IOException; 

public class MainActivity extends Activity implements MediaPlayer.OnPreparedListener { 

    static Button playButton; 
    static Button pauseButton; 
    static Button stopButton; 
    static SeekBar seekBar; 
    private static MediaPlayer player; 
static Handler handler; 
static Uri audio; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    player = MediaPlayer.create(this, R.raw.airbourne_runnin_wild); 
    Uri audio = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.airbourne_runnin_wild); 
    try { 
     player.setDataSource(getAssets().openFd("raw/airbourne_runnin_wild.mp3").getFileDescriptor()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    playButton = (Button) findViewById(R.id.playButton); 
    pauseButton = (Button) findViewById(R.id.pauseButton); 
    stopButton = (Button) findViewById(R.id.stopButton); 
    seekBar = (SeekBar) findViewById(R.id.seekBar); 

    player.setOnPreparedListener(this); 

    handler = new Handler(); 

    seekBar.setMax(player.getDuration()); 

    playButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      if (!player.isPlaying()) { 
       try { 
        player.setDataSource(getAssets().openFd("raw/airbourne_runnin_wild.mp3").getFileDescriptor()); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       player.start(); 
       updateSeekBar(); 
      } 
     } 
    }); 

    pauseButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      if (player.isPlaying()) { 
       player.pause(); 
      } 
     } 
    }); 

    stopButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      if (player.isPlaying()) { 
       player.stop(); 
       seekBar.setProgress(0); 
       seekBar.invalidate(); 
       try { 
        player.setDataSource(getAssets().openFd("raw/airbourne_runnin_wild.mp3").getFileDescriptor()); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }); 

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 
     @Override 
     public void onProgressChanged(SeekBar seekBar, int i, boolean b) { 
      if (b) { 
       seekChanged(seekBar, i, b); 
      } 
     } 

     @Override 
     public void onStartTrackingTouch(SeekBar seekBar) { 

     } 

     @Override 
     public void onStopTrackingTouch(SeekBar seekBar) { 

     } 
    }); 

    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
     @Override 
     public void onCompletion(MediaPlayer mediaPlayer) { 
      player.stop(); 
      seekBar.setProgress(0); 
      //player.prepareAsync(); 
      seekBar.invalidate(); 
     } 
    }); 
} 


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

@Override 
public void onPrepared(MediaPlayer mediaPlayer) { 
    playButton.setEnabled(true); 
} 

public void seekChanged(SeekBar seekBar, int progress, boolean fromUser) { 
    player.seekTo(progress); 
} 

public void updateSeekBar() { 
    seekBar.setProgress(player.getCurrentPosition()); 

    if (player.isPlaying()) { 
     Runnable notification = new Runnable() { 
      public void run() { 
       updateSeekBar(); 
      } 
     }; 
     handler.postDelayed(notification, 1500); 
    } 
} 
} 

E activity_main. xml:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
android:paddingBottom="@dimen/activity_vertical_margin" 
tools:context=".MainActivity"> 

<TableRow 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 

    <Button 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Play" 
      android:id="@+id/playButton" 
      android:layout_gravity="center_horizontal|top" 
      android:longClickable="false" 
      android:layout_weight="1" 
      android:layout_column="8" 
      android:enabled="false"/> 
</TableRow> 

<TableRow 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 

    <Button 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Pause" 
      android:id="@+id/pauseButton" 
      android:layout_gravity="center_horizontal|top" 
      android:layout_weight="1" 
      android:layout_column="8" 
      android:layout_span="7"/> 
</TableRow> 

<TableRow 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 

    <Button 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Stop" 
      android:id="@+id/stopButton" 
      android:layout_column="8" 
      android:layout_span="24" 
      android:layout_weight="1"/> 
</TableRow> 

<TableRow 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 
</TableRow> 

<TableRow 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 

    <SeekBar 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/seekBar" 
      android:layout_column="8" 
      android:layout_span="24" 
      android:layout_weight="1"/> 
</TableRow> 

Se qualcuno potesse aiutarmi a risolvere questo errore, sarebbe molto apprezzato. Ho già cercato soluzioni e provato più soluzioni, ma nessuna sembrava funzionare correttamente.

EDIT: ho cambiato un po 'di codice:

La mia domanda è ancora sull'errore, e questo è ora il mio codice modificato:

import android.app.Activity; 
import android.media.MediaPlayer; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Handler; 
import android.view.Menu; 
import android.view.View; 
import android.widget.Button; 
import android.widget.SeekBar; 

import java.io.IOException; 

public class MainActivity extends Activity implements MediaPlayer.OnPreparedListener { 

static Button playButton; 
static Button pauseButton; 
static Button stopButton; 
static SeekBar seekBar; 
private static MediaPlayer player; 
static Handler handler; 
static Uri audio; 
static boolean canMakeCall = false; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    player = MediaPlayer.create(this, R.raw.airbourne_runnin_wild); 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    playButton = (Button) findViewById(R.id.playButton); 
    pauseButton = (Button) findViewById(R.id.pauseButton); 
    stopButton = (Button) findViewById(R.id.stopButton); 
    seekBar = (SeekBar) findViewById(R.id.seekBar); 

    if (canMakeCall = true) { 
     player.setOnPreparedListener(this); 

     handler = new Handler(); 

     seekBar.setMax(player.getDuration()); 

     playButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View view) { 
       if (!player.isPlaying()) { 
        player.start(); 
        updateSeekBar(); 
       } 
      } 
     }); 

     pauseButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View view) { 
       if (player.isPlaying()) { 
        player.pause(); 
       } 
      } 
     }); 

     stopButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View view) { 
       if (player.isPlaying()) { 
        player.stop(); 
        seekBar.setProgress(0); 
        seekBar.invalidate(); 
        try { 
         player.prepare(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }); 

     seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 
      @Override 
      public void onProgressChanged(SeekBar seekBar, int i, boolean b) { 
       if (b) { 
        seekChanged(seekBar, i, b); 
       } 
      } 

      @Override 
      public void onStartTrackingTouch(SeekBar seekBar) { 

      } 

      @Override 
      public void onStopTrackingTouch(SeekBar seekBar) { 

      } 
     }); 

     player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
      @Override 
      public void onCompletion(MediaPlayer mediaPlayer) { 
       mediaPlayer.stop(); 
       //player.stop(); 

       seekBar.setProgress(0); 
       //player.prepareAsync(); 
       seekBar.invalidate(); 
      } 
     }); 
    } 
} 


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

@Override 
public void onPrepared(MediaPlayer mediaPlayer) { 
    playButton.setEnabled(true); 
    canMakeCall = true; 
} 

public void seekChanged(SeekBar seekBar, int progress, boolean fromUser) { 
    player.seekTo(progress); 
} 

public void updateSeekBar() { 
    seekBar.setProgress(player.getCurrentPosition()); 

    if (player.isPlaying()) { 
     Runnable notification = new Runnable() { 
      public void run() { 
       updateSeekBar(); 
      } 
     }; 
     handler.postDelayed(notification, 1500); 
    } 
} 
} 

Ho cercato di ottenere le nozioni di base di lavoro senza anche una barra di ricerca, giusto per assicurarsi che non stia causando un errore ma si trova da qualche parte all'interno della logica del codice play/pause/stop perché stava producendo lo stesso errore anche con il codice della barra di ricerca omesso.

+0

possibile duplicato del [Problemi MediaPlayer Android: "Errore (-38, 0)" e "fermata in stato 1"] (http : //stackoverflow.com/questions/11913108/android-mediaplayer-problems-error-38-0-and-stop-called-in-state-1) – rds

risposta

8

Il problema è una volta che lo hai fermato, tu di nuovo setDataSource. È necessario quindi chiamare prepare()

player.setDataSource(getAssets().openFd("raw/airbourne_runnin_wild.mp3").getFileDescriptor()); 
player.prepare(); 

Ogni volta che si chiama setDataSource() su di esso dovrai prepare() di nuovo. Pensa a ciò caricando il file, preparandosi per la riproduzione.

A proposito, noto che si confonde chiamando lo MediaPlayer.create() e si chiama anche setDataSource() più volte per lo stesso file. Non c'è bisogno di farlo. Una volta creato e preparato MediaPlayer (che chiama per te .create()), puoi semplicemente chiamare .stop(), .pause(), .play(), senza necessità di reimpostarlo tutto il tempo.

+0

Ho appena cambiato il codice per rimuovere .setDataSource e il associate try ... catch statements ma il codice sta ancora producendo lo stesso errore. Quando premo play, inizia a giocare bene e la SeekBar si muove bene, anche la pausa funziona bene e poi la interrompo ma la barra di ricerca non si azzera a zero per qualche motivo, ecco dove iniziano gli errori. – uberdum05

+0

È difficile dire cosa sta succedendo ora che hai cambiato codice, e non corrisponde alla tua domanda, e non c'è stacktrace con il numero di linea da vedere. Non sono sicuro che la tua domanda riguardi la tua barra di ricerca o l'errore originale di smettere di essere chiamato nello stato sbagliato. Se fossi in te, farei in modo che le basi funzionassero senza alcuna barra di ricerca. –

+0

Vedere le mie modifiche sopra, la risposta ha richiesto un po 'di tempo perché il server DNS è morto sul mio lavoro. – uberdum05

1

Ho risolto questo problema rimuovendo lo player.stop() che veniva chiamato quando il lettore ha terminato la canzone a causa di player.setOnCompletionListener(). Questo ha ora risolto il problema e il giocatore sta funzionando perfettamente.

0

Ho risolto questo problema con `mediaPlayer.prepare(); Il mio problema è di circa radio streaming dal vivo e ho raggiungere questo problema come sottostante Codice:

if (!radioIsOpen) { 
       try { 
        mediaPlayer = new MediaPlayer(); 
        mediaPlayer 
          .setDataSource(URL); 
        mediaPlayer.prepare(); 
       } catch (Exception e) { 
       } 

       mediaPlayer.setOnPreparedListener(new OnPreparedListener() { 

        public void onPrepared(MediaPlayer mp) { 
         mediaPlayer.start(); 
        } 
       }); 
       Toast.makeText(getBaseContext(), "Radio is opening...", 2).show(); 
      } else { 
       if (mediaPlayer.isPlaying()) { 
        mediaPlayer.stop(); 
        mediaPlayer.release(); 
        Toast.makeText(getBaseContext(), "Radio is closing...", 2).show(); 
       } 
      }