私はかなり長い間この問題に悩まされてきました。私が作成した mediaPlayer では、最初の再生段階ではすべてがスムーズに実行されますが、ユーザーが次または前のオプションを選択すると、アプリケーション(0,-107) error
はattempt to call getDuration without a valid mediaplayer
コード:
public void playPodCast(int index) {
try {
urlToSend = toGet.get(index).get("URL").toString();
mediaPlayer.reset();
mediaPlayer.setDataSource(urlToSend);
mediaPlayer.prepareAsync();
onPlayerLoad();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
ここでonPlayerLoad()
は、mediaPlayer の読み込み中にすべてのビューを非表示にする方法にすぎません。
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
onPlayerLoaded();
updateProgressBar();
mediaPlayer.start();
}
onPlayerLoaded()
負荷がビューに戻ります。
public void updateProgressBar() {
seekHandler.postDelayed(updateSeekTime, 100);
}
private Runnable updateSeekTime = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
long totalDuration = mediaPlayer.getDuration();
long currentDuration = mediaPlayer.getCurrentPosition();
// Displaying the total time duration
seekRight.setText("" + utils.milliSecondsToTimer(totalDuration));
// Displaying completed playing time
seekLeft.setText("" + utils.milliSecondsToTimer(currentDuration));
// Updating the SeekBar progress
int progress = (int) (utils.getProgressPercentage(currentDuration,
totalDuration));
seekBar.setProgress(progress);
seekHandler.postDelayed(this, 100);
}
};
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
// @Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
seekHandler.removeCallbacks(updateSeekTime);
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
seekHandler.removeCallbacks(updateSeekTime);
int totalDuration = mediaPlayer.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(),
totalDuration);
// forward or backward to certain seconds
mediaPlayer.seekTo(currentPosition);
// update timer progress again
updateProgressBar();
}
ここ、private Handler seekHandler = new Handler();
前に言ったように、 への最初の呼び出しでplayPodCast(index)
エラーは発生せず、非常にスムーズに動作します。しかし、ユーザーが次のボタンと前のボタンをクリックすると、エラーが生成されます。次のメソッドと前のメソッドは、なしで実装された場合、エラーを出さずupdateProgressBar()
、すべてがバグなく実行されます。では、なぜこのエラーが発生するのですか? 理由がわかりません...助けてください。
次のボタンの実装は次のとおりです。
btnNext.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (getPosition == totalList - 1) {
getPosition = 0;
playPodCast(getPosition);
} else {
getPosition = getPosition + 1;
playPodCast(getPosition);
}
}
});
はgetPosition
、参照されているメディア ファイルの位置です。
そして、私も試しました
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mediaPlayer.start();
onPlayerLoaded();
updateProgressBar();
}
更新 1:
を使用するとエラーが発生することがわかりました。prepareAsync()
プログラムは正常に動作しますprepare()
が、非常に遅いです。