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