1
保持模式开启/关闭后,我的Android应用程序无法再次播放音乐。Android开发:在“保持模式”开启/关闭后,MediaPlayer无法工作
我的代码在开头工作正常(歌曲的声音)。 但当用户按下保持按钮时,应用程序无法继续播放(保持后再次返回屏幕)。
通过调试我已经检查,当你按下挂机键(重新启动手机),你的内心onResume
(明显)进入,但mediaPlayer.prepare()
抛出java.lang.IllegalStateException
(catch块捕获)与消息:prepareAsync称为状态0
onResume()
后,我调用的方法play()和它抛出这些错误:
尝试在错误的状态下执行seekTo
错误(-38,0)
尝试调用getDuration没有有效的媒体播放器
错误(-38,0)
任何想法? :S
这是我的代码:Fragment.java
public class FragmentMediaPlayer extends Fragment implements OnSeekBarChangeListener {
private MediaPlayer mediaPlayer;
public TextView duration;
private double timeElapsed = 0, finalTime = 0;
private int forwardTime = 5000, backwardTime = 5000;
private Handler durationHandler = new Handler();
private SeekBar seekBar;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View rootView = inflater.inflate(R.layout.media_player, container,
false);
// initialize views
initializeViews(rootView);
return rootView;
}
public void initializeViews(View rootView) {
mediaPlayer = MediaPlayer.create(getActivity(), R.raw.song);
try {
mediaPlayer.prepare();
} catch (IllegalStateException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finalTime = mediaPlayer.getDuration();
duration = (TextView) rootView.findViewById(R.id.songDuration);
duration.setText(String.format(
"%d min, %d sec",
0,0));
seekBar = (SeekBar) rootView.findViewById(R.id.seekBar);
seekBar.setMax((int) finalTime);
seekBar.setOnSeekBarChangeListener(this);
ImageButton playButton = (ImageButton) rootView.findViewById(R.id.media_play);
playButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
play();
}
});
ImageButton media_pause = (ImageButton) rootView.findViewById(R.id.media_pause);
media_pause.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
pause(v);
}
});
ImageButton media_ff = (ImageButton) rootView.findViewById(R.id.media_ff);
media_ff.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
forward(v);
}
});
ImageButton media_rew = (ImageButton) rootView.findViewById(R.id.media_rew);
media_rew.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
rewind(v);
}
});
}
// play mp3 song
public void play() {
timeElapsed = mediaPlayer.getCurrentPosition();
seekBar.setProgress((int) timeElapsed);
mediaPlayer.seekTo((int) timeElapsed) ;
mediaPlayer.start();
durationHandler.postDelayed(updateSeekBarTime, 100);
}
// handler to change seekBarTime
private Runnable updateSeekBarTime = new Runnable() {
public void run() {
// get current position
timeElapsed = mediaPlayer.getCurrentPosition();
// set seekbar progress
seekBar.setProgress((int) timeElapsed);
// set time remaing
//double timeRemaining = finalTime - timeElapsed;
duration.setText(String.format(
"%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes((long) timeElapsed),
TimeUnit.MILLISECONDS.toSeconds((long) timeElapsed)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS
.toMinutes((long) timeElapsed))));
// repeat yourself that again in 100 miliseconds
durationHandler.postDelayed(this, 100);
}
};
// pause mp3 song
public void pause(View view) {
mediaPlayer.pause();
timeElapsed = mediaPlayer.getCurrentPosition();
}
// go forward at forwardTime seconds
public void forward(View view) {
// check if we can go forward at forwardTime seconds before song endes
if ((timeElapsed + forwardTime) <= finalTime) {
timeElapsed = timeElapsed + forwardTime;
// seek to the exact second of the track
mediaPlayer.seekTo((int) timeElapsed);
}
}
// go backwards at backwardTime seconds
public void rewind(View view) {
// check if we can go back at backwardTime seconds after song starts
if ((timeElapsed - backwardTime) > 0) {
timeElapsed = timeElapsed - backwardTime;
// seek to the exact second of the track
mediaPlayer.seekTo((int) timeElapsed);
}
}
@Override
public void onResume() {
super.onResume();
try {
mediaPlayer.prepare();
} catch (IllegalStateException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
play();
}
@Override
public void onPause() {
super.onPause();
mediaPlayer.pause();
}
@Override
public void onStop() {
// Stop updates and Disconnect from LocationServices
mediaPlayer.stop();
durationHandler.removeCallbacks(updateSeekBarTime);
super.onStop();
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser) {
mediaPlayer.seekTo(progress);
seekBar.setProgress(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
这里是我的layout.xml:
<ScrollView 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:fillViewport="true"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/songName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/play_text" />
<TextView
android:id="@+id/songDuration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp"
android:gravity="center_horizontal"
android:orientation="horizontal" >
<ImageButton
android:id="@+id/media_rew"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:contentDescription="@string/rewind"
android:src="@android:drawable/ic_media_rew" />
<ImageButton
android:id="@+id/media_pause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:contentDescription="@string/pause"
android:src="@android:drawable/ic_media_pause" />
<ImageButton
android:id="@+id/media_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:contentDescription="@string/play"
android:src="@android:drawable/ic_media_play" />
<ImageButton
android:id="@+id/media_ff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:contentDescription="@string/forward"
android:src="@android:drawable/ic_media_ff" />
</LinearLayout>
</LinearLayout>
</ScrollView>
后,我已看过一些帖子,我已经把这个在我的代码,并从法的play()quited mediaPlayer.start(),但仍然有同样的问题: mediaPlayer.setOnPreparedListener(新OnPreparedListener() { \t @覆盖 \t公共无效onPrepared(MediaPlayer的熔点){ \t mp.start(); \t} \t}); – 2014-10-31 12:12:32
我检查了MediaPlayer状态图:http://developer.android.com/images/mediaplayer_state_diagram.gif 我在暂停()后调用start()。我错过了一些东西...... – 2014-10-31 12:21:03
你不应该在'已暂停'状态中调用'prepare()'。只有'start(),stop(),seekTo()'在'Paused'状态下有效。在你的情况下,只需在'onResume()'中调用'play()'方法即可。 – 2014-11-03 15:28:13