Android - SeekBar 和 MediaPlayer

Dan*_*ele 5 java xml android seekbar media-player

我需要在我的应用程序中连接我SeekBarMediaPlayer

我通过 xml 设置了 SeekBar,如下所示:

<SeekBar
        android:id="@+id/song_seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"/>
Run Code Online (Sandbox Code Playgroud)

并按照这个SO 答案来实现它。

这是我的代码:

public class Song_main extends AppCompatActivity {
private final int SONG_REQUEST_CODE = 1;

private Uri song;
private TextView selectSong;
private SeekBar seekBar;
private Handler handler;
private MediaPlayer mediaPlayer;


private boolean repeatPressedTwice = false;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.app_bar_song_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.song_main_toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayShowTitleEnabled(false);

    seekBar = (SeekBar) findViewById(R.id.song_seekbar);
    handler = new Handler();

    notSelected();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.song, menu);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.song_plus) {
        Intent selectIntent = new Intent(Intent.ACTION_GET_CONTENT);
        selectIntent.setType("audio/*");
        startActivityForResult(selectIntent, SONG_REQUEST_CODE);
    }

    return true;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == SONG_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        if ((data != null) && (data.getData()!=null)) {
            song = data.getData();
            setup();
        }
    }
}

private void notSelected() {
    selectSong = (TextView) findViewById(R.id.select_song_textview);
    selectSong.setText(getResources().getString(R.string.song_not_selected));
}

public void onPlayButtonClicked(View v) {
    ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
    if (!mediaPlayer.isPlaying()) {
        mediaPlayer.start();
        pb.setImageResource(R.drawable.pause);

        updateSeekBar();

    } else {
        mediaPlayer.pause();
        pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
    }
}

public void onControlsClicked(View v) {
    if (v.getId() == R.id.fast_forward) {
        int pos = mediaPlayer.getCurrentPosition();
        pos += 1500;
        mediaPlayer.seekTo(pos);
    }
    else if (v.getId() == R.id.fast_backward) {
        int pos = mediaPlayer.getCurrentPosition();
        pos -= 1500;
        mediaPlayer.seekTo(pos);
    }
    else if (v.getId() == R.id.skip_backward) {
        mediaPlayer.seekTo(0);
    }
}

public void onRepeatClicked(View v) {
    if (!repeatPressedTwice) {
        // TODO: change visual color of repeat button
        mediaPlayer.setLooping(true);
        Toast.makeText(this, "repeat enabled", Toast.LENGTH_SHORT).show();
        repeatPressedTwice = true;
    } else {
        mediaPlayer.setLooping(false);
    }

}

private void setup() {
    /* the song has been select setup the interface */


    /* displays song name in title */
    TextView titleView = (TextView) findViewById(R.id.song_appbar_title);
    String songName;

    ContentResolver contentResolver = this.getContentResolver();
    Cursor cursor = contentResolver.query(song, null, null, null, null);

    if (cursor != null && cursor.moveToFirst()) {
        songName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
        titleView.setText(songName);
    }


    /* removes the notSelected String */
    selectSong.setVisibility(View.GONE);

    /* setup media player */
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    try {
        mediaPlayer.setDataSource(getApplicationContext(), song);
        mediaPlayer.prepareAsync();
    } catch (IOException e) {
        Toast.makeText(this, "file not found", Toast.LENGTH_SHORT).show();
    }

    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            /* show media player layout */
            RelativeLayout mpl = (RelativeLayout) findViewById(R.id.media_player_layout);
            mpl.setVisibility(View.VISIBLE);

            mediaPlayer.start();
            ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
            pb.setImageResource(R.drawable.pause);

        }
    });

    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
            pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
        }
    });



    seekBar = (SeekBar) findViewById(R.id.song_seekbar);
    seekBar.setMax(mediaPlayer.getDuration()); 

    updateSeekBar();


}

private void updateSeekBar() {
    seekBar.setProgress(mediaPlayer.getCurrentPosition()/1000);
    handler.postDelayed(runnable, 1000);
}

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        updateSeekBar();
    }
};


@Override
public void onStop() {
    super.onStop();
    if (mediaPlayer!=null)
        mediaPlayer.stop();
}
}
Run Code Online (Sandbox Code Playgroud)

过程是从onOptionsItemSelected方法开始的。

searchBar 行为正确,每秒递增。现在的问题是它在歌曲结束之前就结束了。

我尝试添加

seekBar.setMax(mediaPlayer.getDuration());
Run Code Online (Sandbox Code Playgroud)

在该setup方法中,但这会导致栏根本不移动。

Waq*_*ari 5

您需要定义单独的Runnable并在启动后每 x 毫秒(取决于您)触发它MediaPlayer

定义一个函数updateSeekbar,例如

private void updateSeekBar() {
    audioSeek.setProgress(player.getCurrentPosition());
    txtCurrentTime.setText(milliSecondsToTimer(player.getCurrentPosition()));
    seekHandler.postDelayed(runnable, 50);
}
Run Code Online (Sandbox Code Playgroud)

Runnable

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        updateSeekBar();
    }
};
Run Code Online (Sandbox Code Playgroud)

现在您只需updateSeekbar在比赛开始时调用一次即可。在你的情况下:

public void onPlayButtonClicked(View v) {
    ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
    if (!mediaPlayer.isPlaying()) {
        mediaPlayer.start();
        pb.setImageResource(R.drawable.pause);

        updateSeekBar();

    } else {
        mediaPlayer.pause();
        pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
    }
}
Run Code Online (Sandbox Code Playgroud)

供参考

函数的milliSecondsToTimer工作原理如下

private String milliSecondsToTimer(long milliseconds) {
    String finalTimerString = "";
    String secondsString = "";

    // Convert total duration into time
    int hours = (int) (milliseconds / (1000 * 60 * 60));
    int minutes = (int) (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
    int seconds = (int) ((milliseconds % (1000 * 60 * 60)) % (1000 * 60) / 1000);
    // Add hours if there
    if (hours > 0) {
        finalTimerString = hours + ":";
    }

    // Prepending 0 to seconds if it is one digit
    if (seconds < 10) {
        secondsString = "0" + seconds;
    } else {
        secondsString = "" + seconds;
    }

    finalTimerString = finalTimerString + minutes + ":" + secondsString;

    // return timer string
    return finalTimerString;
}
Run Code Online (Sandbox Code Playgroud)

更新

setMax打错地方了。更新setup()函数如下

private void setup() {
    /* the song has been select setup the interface */
    /* displays song name in title */
    TextView titleView = (TextView) findViewById(R.id.song_appbar_title);
    String songName;

    ContentResolver contentResolver = this.getContentResolver();
    Cursor cursor = contentResolver.query(song, null, null, null, null);

    if (cursor != null && cursor.moveToFirst()) {
        songName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
        titleView.setText(songName);
    }


    /* removes the notSelected String */
    selectSong.setVisibility(View.GONE);

    /* setup media player */
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    try {
        mediaPlayer.setDataSource(getApplicationContext(), song);
        mediaPlayer.prepareAsync();
    } catch (IOException e) {
        Toast.makeText(this, "file not found", Toast.LENGTH_SHORT).show();
    }

    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
        /* show media player layout */
            seekBar.setMax(mediaPlayer.getDuration());

            RelativeLayout mpl = (RelativeLayout) findViewById(R.id.media_player_layout);
            mpl.setVisibility(View.VISIBLE);
            mediaPlayer.start();

            updateSeekBar();


            ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
            pb.setImageResource(R.drawable.pause);

        }
    });

    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            ImageButton pb = (ImageButton) findViewById(R.id.song_play_button);
            pb.setImageResource(R.drawable.ic_play_arrow_white_24dp);
        }
    });

}
Run Code Online (Sandbox Code Playgroud)