2013-07-18 25 views
9

Tôi đã xem các trang web khác nhau tìm kiếm giải pháp cho vấn đề này trong mã của tôi. Nó là một trình phát âm thanh cơ bản với 3 nút: phát, tạm dừng và dừng. Chơi và tạm dừng công việc ok và do đó không dừng lại nhưng một khi âm thanh đã được dừng lại nó từ chối bắt đầu lại, ném một lỗi:Lỗi MediaPlayer của Android (-38, 0) "dừng gọi ở trạng thái 0"

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

Đây là MainActivity.java tôi:

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

Và 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> 

Nếu bất cứ ai có thể giúp tôi giải quyết lỗi này, nó sẽ là Nhiều đánh giá cao. Tôi đã tìm kiếm các giải pháp và thử nhiều, nhưng dường như không hoạt động đúng.

EDIT: Tôi đã thay đổi một chút mã:

Câu hỏi của tôi vẫn là về lỗi, và điều này bây giờ là mã sửa của tôi:

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

Tôi đã cố gắng nhận được những điều cơ bản làm việc mà không một thanh tìm kiếm quá, chỉ để đảm bảo rằng không gây ra lỗi nhưng nó nằm đâu đó trong logic của mã play/pause/stop vì nó đã tạo ra cùng một lỗi ngay cả khi mã tìm kiếm bị bỏ qua.

+0

có thể trùng lặp với [Android MediaPlayer Problems: "Error (-38, 0)" và "stop called in state 1"] (http : //stackoverflow.com/questions/11913108/android-mediaplayer-problems-error-38-0-and-stop-called-in-state-1) – rds

Trả lời

8

Vấn đề là khi bạn đã dừng lại, bạn setDataSource một lần nữa. Bạn phải sau đó gọi prepare()

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

Bất cứ lúc nào bạn gọi setDataSource() vào nó, bạn sẽ cần phải prepare() nó một lần nữa. Hãy nghĩ về nó khi tải tệp, chuẩn bị phát lại.

Bằng cách tôi nhận thấy bạn trộn lên gọi MediaPlayer.create() và cũng gọi setDataSource() nhiều lần cho cùng một tệp. Không cần phải làm điều này. Khi MediaPlayer được tạo và chuẩn bị (gọi số .create() cho bạn), bạn chỉ có thể gọi .stop(), .pause(), .play() trên đó, không cần phải đặt lại mọi lúc.

+0

Tôi vừa thay đổi mã để xóa tệp .setDataSource và liên kết thử ... nắm bắt báo cáo nhưng mã vẫn còn sản xuất cùng một lỗi. Khi tôi nhấn play, nó bắt đầu chơi tốt và SeekBar di chuyển dọc theo tốt, tạm dừng hoạt động tốt quá và sau đó tôi dừng lại nhưng thanh tìm kiếm không đặt lại về 0 vì lý do nào đó, đó là nơi các lỗi bắt đầu. – uberdum05

+0

Thật khó để nói những gì đang diễn ra mà bạn đã thay đổi mã, và nó không phù hợp với câu hỏi của bạn, và không có stacktrace với số dòng để xem. Tôi không chắc liệu câu hỏi của bạn là về thanh tìm kiếm của bạn hay về lỗi ban đầu của việc dừng được gọi trong trạng thái sai. Nếu tôi là bạn tôi sẽ có được những điều cơ bản làm việc mà không có bất kỳ seekbar. –

+0

Vui lòng xem các chỉnh sửa của tôi ở trên, câu trả lời mất một lúc nữa vì máy chủ DNS đã qua đời tại nơi làm việc của tôi. – uberdum05

1

Tôi đã khắc phục sự cố này bằng cách xóa player.stop() đã được gọi khi người chơi kết thúc bài hát vì player.setOnCompletionListener(). Điều này đã giải quyết được vấn đề và người chơi đang hoạt động hoàn hảo.

0

Tôi đã khắc phục sự cố này bằng `mediaPlayer.prepare(); Vấn đề của tôi là về phát trực tiếp radio trực tiếp và tôi đạt được vấn đề này như dưới đây:

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