2013-07-18 9 views
9

Przeglądałem różne strony internetowe szukające rozwiązania tego problemu w moim kodzie. Jest to podstawowy odtwarzacz audio z 3 przyciskami: odtwarzanie, pauza i zatrzymanie. Play i wstrzymać pracę ok i tak nie zatrzyma, ale gdy dźwięk został zatrzymany odmawia uruchomić ponownie, wyrzucając błąd:Błąd Android MediaPlayer (-38, 0) "stop wywołany w stanie 0"

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

To mój 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); 
    } 
} 
} 

I 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> 

Jeśli ktoś może mi pomóc rozwiązać ten problem, byłoby bardzo doceniane. Już szukałem rozwiązań i próbowałem wielu, ale żaden nie działał poprawnie.

EDIT: Zmieniłam trochę kodu:

moje pytanie jest nadal o błędzie, a to jest teraz mój edytowany kod:

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

Próbowałem się z podstawami pracy bez także pasek wyszukiwania, aby upewnić się, że nie powoduje błędu, ale leży gdzieś w logice kodu play/pause/stop, ponieważ powodował ten sam błąd nawet po pominięciu kodu seekbar.

+0

możliwe duplikat [Android MediaPlayer problemy: "Błąd (-38, 0)" i "stop zwany w stanie 1"] (http : //stackoverflow.com/questions/11913108/android-mediaplayer-problems-error-38-0-and-stop-called-in-state-1) – rds

Odpowiedz

8

Problem jest po tym, jak go zatrzymałeś, ponownie setDataSource. Trzeba wtedy zadzwonić prepare()

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

każdej chwili zadzwonić setDataSource() na nim będzie znowu trzeba prepare() go. Pomyśl o tym, jak ładować plik, przygotowując się do odtwarzania.

Przy okazji zauważam, że mieszasz się, dzwoniąc pod numer MediaPlayer.create(), a także wielokrotnie dzwonisz pod numer setDataSource() dla tego samego pliku. Nie ma takiej potrzeby. Po utworzeniu i przygotowaniu MediaPlayera (który dzwoni pod numer .create()), możesz po prostu zadzwonić pod numer .stop(), .pause(), .play(), bez potrzeby resetowania go przez cały czas.

+0

Właśnie zmieniłem kod, aby usunąć .setDataSource i powiązane instrukcje try ... catch, ale kod nadal generuje ten sam błąd. Kiedy naciskam play, zaczyna grać dobrze i SeekBar porusza się dobrze, pauza działa dobrze, a potem zatrzymuję go, ale pasek wyszukiwania nie resetuje się do zera z jakiegoś powodu, to tam, gdzie zaczynają się błędy. – uberdum05

+0

Trudno powiedzieć, co się dzieje, gdy zmieniłeś kod, a to nie pasuje do twojego pytania, i nie ma stosu śledzenia z numerem linii, który można zobaczyć. Nie jestem pewien, czy twoje pytanie dotyczy paska wyszukiwania, czy pierwotnego błędu, z którego nie można się połączyć w niewłaściwym stanie. Gdybym był tobą, podstawiłbym pracę bez paska wyszukiwania. –

+0

Proszę zobaczyć moje edycje powyżej, odpowiedź też trwała zbyt długo, ponieważ serwer DNS zginął podczas mojej pracy. – uberdum05

1

Rozwiązałem ten problem, usuwając player.stop(), który był wywoływany, gdy odtwarzacz zakończył utwór z powodu player.setOnCompletionListener(). To rozwiązało problem i odtwarzacz działa idealnie.

0

Naprawiłem ten problem przez `mediaPlayer.prepare(); Mój problem jest o żywej radiowej transmisji strumieniowej i osiągnąć ten problem jak poniżej kodu:

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(); 
       } 
      } 
Powiązane problemy