クリック時にsetProgressを設定したときに、シークバーを正しく機能させる方法に問題があります。進行状況は、クリックした場所に応じて、最初/中間/最後にジャンプします。どのように解決することが可能ですか?
私の試み:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_player);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
videoPath = getIntent().getExtras().getString("videoPath");
videoView = (VideoView) findViewById(R.id.vvPlayer);
seekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(this);
....
}
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
seekBar.setMax(mp.getDuration());
System.out.println("curpos" + mp.getCurrentPosition());
new Thread(new Runnable() {
public void run() {
try {
while (mPlayer != null && mPlayer.getCurrentPosition() < mPlayer.getDuration()) {
seekBar.setProgress(mPlayer.getCurrentPosition());
Message msg = new Message();
int millis = mPlayer.getCurrentPosition();
msg.obj = millis / 1000;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("interrupt exeption" + e);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("my Exception" + e);
}
}
}).start();
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// TODO Auto-generated method stub
if (fromUser) {
Log.e("onProgressChanged: ", Integer.toString(progress));
mPlayer.seekTo(progress);
}
}
完全なコード:
public class VideoPlayerActivity extends Activity implements Callback, OnSeekBarChangeListener, OnTouchListener, OnErrorListener, OnCompletionListener, OnPreparedListener {
MediaPlayer mPlayer;
AssetFileDescriptor afd;
VideoView videoView;
SurfaceHolder holder;
MediaController mController;
String videoPath;
SeekBar seekBar;
ImageButton mPlay, mStop, mPause;
TextView mCurDuration, mDuration;
int position = 0;
Handler handler = new Handler();
Runnable r;
boolean controlsVisibility = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_player);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
mDuration = (TextView) findViewById(R.id.tvDuration);
mCurDuration = (TextView) findViewById(R.id.tvCurDuration);
videoPath = getIntent().getExtras().getString("videoPath");
videoView = (VideoView) findViewById(R.id.vvPlayer);
seekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(this);
seekBar.setFocusable(false);
videoView.setOnTouchListener(this);
mPlay = (ImageButton) findViewById(R.id.play);
mPause = (ImageButton) findViewById(R.id.pause);
mStop = (ImageButton) findViewById(R.id.stop);
mController = new MediaController(this);
videoView.setMediaController(mController);
holder = videoView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mPlay.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
Log.e("Play:", " is Pressed!");
if (mPlayer == null)
playVideo();
mPlayer.start();
}
});
mPause.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
Log.e("Pause:", " is Pressed!");
if (mPlayer != null) {
handler.removeCallbacks(r);
controlsVisibility=true;
AutoHideControls();
Log.e("mPlayer status: ", "Not Null");
if (mPlayer.isPlaying())
Log.e("mPlayer status: ", "Not Null");
mPlayer.pause();
}
}
});
mStop.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
Log.e("Stop:", " is Pressed!");
if (mPlayer != null) {
handler.removeCallbacks(r);
controlsVisibility=true;
AutoHideControls();
seekBar.setProgress(0);
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
}
});
}
private void playVideo() {
try {
if (afd != null && mPlayer != null) {
mPlayer.start();
return;
}
Log.e("VideoPath:", videoPath);
if (videoPath != "") {
afd = getAssets().openFd(videoPath);
// "videos/start.mp4"
mPlayer = new MediaPlayer();
mPlayer.setOnErrorListener(this);
mPlayer.setOnCompletionListener(this);
mPlayer.setOnPreparedListener(this);
mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mPlayer.setScreenOnWhilePlaying(true);
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDisplay(holder);
mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mPlayer.prepare();
mPlayer.start();
handler.removeCallbacks(r);
controlsVisibility=true;
AutoHideControls();
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void surfaceCreated(SurfaceHolder holder) {
runOnUiThread(new Runnable() {
public void run() {
playVideo();
}
});
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e("Debug:", "onError---> what:" + what + " extra:" + extra);
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
return true;
}
@Override
public void onCompletion(MediaPlayer mp) {
mPlayer.release();
finish();
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
}
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (controlsVisibility) {
controlsVisibility = false;
mPlay.setVisibility(View.GONE);
mPause.setVisibility(View.GONE);
mStop.setVisibility(View.GONE);
seekBar.setVisibility(View.GONE);
handler.removeCallbacks(r);
} else {
controlsVisibility = true;
mPlay.setVisibility(View.VISIBLE);
mPause.setVisibility(View.VISIBLE);
mStop.setVisibility(View.VISIBLE);
seekBar.setVisibility(View.VISIBLE);
AutoHideControls();
}
return false;
}
public void AutoHideControls() {
r = new Runnable() {
public void run() {
controlsVisibility = false;
mPlay.setVisibility(View.GONE);
mPause.setVisibility(View.GONE);
mStop.setVisibility(View.GONE);
seekBar.setVisibility(View.GONE);
}
};
handler.removeCallbacks(r);
handler.postDelayed(r, 4000);
}
@Override
public void onPrepared(MediaPlayer mp) {
seekBar.setMax(mp.getDuration());
new Thread(new Runnable() {
public void run() {
int currentPosition = 0;
int total = mPlayer.getDuration();
seekBar.setMax(total);
while (mPlayer != null && currentPosition < total) {
try {
Thread.sleep(1000);
currentPosition = mPlayer.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
seekBar.setProgress(currentPosition);
}
}
}).start();
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// TODO Auto-generated method stub
if (fromUser) {
Log.e("onProgressChanged: ", Integer.toString(progress));
mPlayer.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
同じですが、AsyncTask 全体を通して (ただし、同じ結果 - まだジャンプしています):
@Override
public void onPrepared(MediaPlayer mp) {
seekBar.setMax(mp.getDuration());
new Async().execute();
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// TODO Auto-generated method stub
if (fromUser) {
Log.e("onProgressChanged: ", Integer.toString(progress));
mPlayer.seekTo(progress);
seekBar.setProgress(progress);
Log.e("SeekedProgressTime: ", Integer.toString(mPlayer.getCurrentPosition()));
Log.e("SeekedProgressTime: ", Integer.toString(seekBar.getProgress()));
}
}
class Async extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
int currentPosition = 0;
int total = mPlayer.getDuration();
seekBar.setMax(total);
while (mPlayer != null && currentPosition < total) {
Log.e("Current mPlayer time in Thread: ", Integer.toString(mPlayer.getCurrentPosition()));
Log.e("Current seekBar time in Thread: ", Integer.toString(seekBar.getProgress()));
try {
Thread.sleep(1000);
currentPosition = mPlayer.getCurrentPosition();
} catch (InterruptedException e) {
} catch (Exception e) {
}
seekBar.setProgress(currentPosition);
}
return null;
}
}
たぶん、私は AsyncTask 内で何か間違ったことをしたのでしょう。この seekBar の何が問題なのか理解できません。シークバーのどこかをクリックしたときの実際の位置を確認してください。すべて正しいですが、その位置の値が何らかの形でオーバーライドされます。