0

私は実際にボタン、シークバー、画像を含むアプリを作成しています。ボタンは、音楽の再生/一時停止に使用されます。シークバーを追加する前に、音楽はスムーズに再生されました。しかし、音楽の位置に合わせて進むシークバーのコードを書いた後、音楽は少し途切れ途切れのようです。また、シークバーの位置をリセットして開始し、音楽の再生が終了したらボタンのテキストを「再生」に変更したいと考えています。シークバーを実装した後に音楽が途切れ途切れになる理由を誰か教えてもらえますか? また、音楽の再生が終わった後の対処法を教えてください。私が使用したコードは以下のとおりです。

public class MainActivity extends ActionBarActivity {

private MediaPlayer song;
private SeekBar seekbar;

private final Handler handler = new Handler();

private final Runnable updatePositionRunnable = new Runnable() {
        public void run() {
                updatePosition();
        }
};

//private boolean isPlaying = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }

    seekbar = (SeekBar)findViewById(R.id.musicSeekBar);
    song = MediaPlayer.create( MainActivity.this, R.raw.xyz);   
    seekbar.setMax(song.getDuration());

    final Button playButton = (Button)findViewById(R.id.playButton);


    playButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {


            if(song.isPlaying()){
                playButton.setText("Play");
                song.pause();
                //isPlaying = false;
                handler.removeCallbacks(updatePositionRunnable);
            }
            else{
                playButton.setText("Pause");
                song.start();
                //isPlaying = true;
                updatePosition();
            }
        }
    });

    song.setOnCompletionListener(new OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            playButton.setText("Play");
            //seekbar.setProgress(0);
            //mp.stop();
        }
    });

    seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {


        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {


        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            song.seekTo(progress);
        }
    });
private void updatePosition(){
    handler.removeCallbacks(updatePositionRunnable);

    seekbar.setProgress(song.getCurrentPosition());

    handler.postDelayed(updatePositionRunnable, 2000);
}


@Override
public void onBackPressed() {

    super.onBackPressed();
    song.stop();
    song.release();
}
4

2 に答える 2

0

これは私のために働いた:

sBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        boolean userTouch;
        @Override
        public void onStopTrackingTouch(SeekBar arg0) {
            userTouch = false;
        }
        @Override
        public void onStartTrackingTouch(SeekBar arg0) {
            userTouch = true;
        }
        @Override
        public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
            if(mPlayer.isPlaying() && arg2)
                mPlayer.seekTo(arg1);
            }
    });
于 2014-08-31T19:04:38.060 に答える
0

メソッドからシークバーの進行状況をupdatePosition2 秒ごとに更新するonProgressChangedと、リスナーのメソッドが呼び出され、再生の位置が設定され、わずかなブリップが発生します。onProgressChangedユーザーが SeekBar を操作したときにのみ呼び出されることを期待するかもしれませんが、残念ながらそうではありません。

私はこれに対する明確な解決策を知りません。できることは、呼び出しの直前にコードにブール値フラグを設定することです。これseekbar.setProgressは、次のonProgressChangedコールバックがユーザーによって引き起こされたものではないことを示しているため、無視できます。AtomicBooleanイベントは異なるスレッドから発生する可能性があるため、この目的には を使用する必要があります。

于 2014-07-13T17:24:10.240 に答える