android 怎么设置mediaandroid controller类

MediaController的使用方法
android 的mediaPlayer 有自带的MediaControl.我们不必自己重写这个控件:
A view containing controls for a MediaPlayer. Typically contains
the buttons like "Play/Pause", "Rewind", "Fast Forward" and a
progress slider. It takes care of synchronizing the controls with
the state of the MediaPlayer.
The way to use this class is to instantiate it programatically. The
MediaController will create a default set of controls and put them
in a window floating above your application. Specifically, the
controls will float above the view specified with setAnchorView().
The window will disappear if left idle for three seconds and
reappear when the user touches the anchor view.
Functions like show() and hide() have no effect when
MediaController is created in an xml layout. MediaController will
hide and show the buttons according to these rules:
The "previous" and "next" buttons are
hidden until setPrevNextListeners() has been called
The "previous" and "next" buttons are visible but disabled if
setPrevNextListeners() was called with null listeners
The "rewind" and "fastforward" buttons are shown unless requested
otherwise by using the MediaController(Context, boolean)
constructor with the boolean set to false
package android.
import android.content.C
import android.graphics.PixelF
import android.media.AudioM
import android.os.H
import android.os.M
import android.util.AttributeS
import android.util.L
import android.view.G
import android.view.KeyE
import android.view.LayoutI
import android.view.MotionE
import android.view.V
import android.view.ViewG
import android.view.W
import android.view.WindowM
import android.widget.SeekBar.OnSeekBarChangeL
import com.android.internal.policy.PolicyM
import java.util.F
import java.util.L
public class MediaController extends FrameLayout {
private MediaPlayerControl mP
private Context mC
private View mA
private View mR
private WindowManager mWindowM
private Window mW
private View mD
private ProgressBar mP
private TextView mEndTime, mCurrentT
private boolean mS
private boolean mD
private static final int sDefaultTimeout = 3000;
private static final int FADE_OUT = 1;
private static final int SHOW_PROGRESS = 2;
private boolean mUseFastF
private boolean mFromX
private boolean mListenersS
private View.OnClickListener mNextListener, mPrevL
StringBuilder mFormatB
Formatter mF
private ImageButton mPauseB
private ImageButton mFfwdB
private ImageButton mRewB
private ImageButton mNextB
private ImageButton mPrevB
public MediaController(Context context, AttributeSet attrs) {
super(context, attrs);
mContext =
mUseFastForward =
mFromXml =
public void onFinishInflate() {
if (mRoot != null)
initControllerView(mRoot);
/&在这里设置是否使用FastForward而不是NuseFastForward=false时使用&&
Next/Prevouse按钮所以我们在实例化MediaControl是调用这个构造函数,并且
useFastForward=false&/
public MediaController(Context context, boolean useFastForward)
super(context);
mContext =
mUseFastForward =
initFloatingWindow();
public MediaController(Context context) {
super(context);
mContext =
mUseFastForward =
initFloatingWindow();
private void initFloatingWindow() {
mWindowManager = (WindowManager)
mContext.getSystemService("window");
mWindow = PolicyManager.makeNewWindow(mContext);
mWindow.setWindowManager(mWindowManager, null, null);
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
mDecor = mWindow.getDecorView();
mDecor.setOnTouchListener(mTouchListener);
mWindow.setContentView(this);
mWindow.setBackgroundDrawableResource(android.R.color.transparent);
// While the media controller is up, the volume control keys
// affect the media stream type
mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC);
setFocusable(true);
setFocusableInTouchMode(true);
setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
requestFocus();
private OnTouchListener mTouchListener = new OnTouchListener()
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mShowing) {
public void setMediaPlayer(MediaPlayerControl player) {
updatePausePlay();
public void setAnchorView(View view) {
FrameLayout.LayoutParams frameParams = new
FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
removeAllViews();
View v = makeControllerView();
addView(v, frameParams);
protected View makeControllerView() {
LayoutInflater inflate = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflate.inflate(com.android.internal.R.layout.media_controller,
initControllerView(mRoot);
private void initControllerView(View v) {
mPauseButton = (ImageButton) v
.findViewById(com.android.internal.R.id.pause);
if (mPauseButton != null) {
mPauseButton.requestFocus();
mPauseButton.setOnClickListener(mPauseListener);
mFfwdButton = (ImageButton) v
.findViewById(com.android.internal.R.id.ffwd);
if (mFfwdButton != null) {
mFfwdButton.setOnClickListener(mFfwdListener);
if (!mFromXml) {
mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE
: View.GONE);
mRewButton = (ImageButton) v
.findViewById(com.android.internal.R.id.rew);
if (mRewButton != null) {
mRewButton.setOnClickListener(mRewListener);
if (!mFromXml) {
mRewButton.setVisibility(mUseFastForward ? View.VISIBLE
: View.GONE);
// By default these are hidden. They will be enabled when
// setPrevNextListeners() is called
mNextButton = (ImageButton) v
.findViewById(com.android.internal.R.id.next);
if (mNextButton != null &&
!mFromXml && !mListenersSet)
mNextButton.setVisibility(View.GONE);
mPrevButton = (ImageButton) v
.findViewById(com.android.internal.R.id.prev);
if (mPrevButton != null &&
!mFromXml && !mListenersSet)
mPrevButton.setVisibility(View.GONE);
mProgress = (ProgressBar) v
.findViewById(com.android.internal.R.id.mediacontroller_progress);
if (mProgress != null) {
if (mProgress instanceof SeekBar) {
SeekBar seeker = (SeekBar) mP
seeker.setOnSeekBarChangeListener(mSeekListener);
mProgress.setMax(1000);
mEndTime = (TextView)
v.findViewById(com.android.internal.R.id.time);
mCurrentTime = (TextView) v
.findViewById(com.android.internal.R.id.time_current);
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder,
Locale.getDefault());
installPrevNextListeners();
public void show() {
show(sDefaultTimeout);
//我们可以在这里设置MediaControl显示的位置:由P.x与P.y决定
public void show(int timeout) {
if (!mShowing && mAnchor != null)
setProgress();
int[] anchorpos = new int[2];
mAnchor.getLocationOnScreen(anchorpos);
WindowManager.LayoutParams p = new
WindowManager.LayoutParams();
p.gravity = Gravity.TOP;
p.width = mAnchor.getWidth();
p.height = LayoutParams.WRAP_CONTENT;
p.y = anchorpos[1] + mAnchor.getHeight() - p.
p.format = PixelFormat.TRANSLUCENT;
p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
p.windowAnimations = 0; //
android.R.style.DropDownAnimationD
mWindowManager.addView(mDecor, p);
mShowing =
updatePausePlay();
// cause the progress bar to be updated even if mShowing
// was already true. This happens, for example, if we're
// paused with the progress bar showing the user hits play.
mHandler.sendEmptyMessage(SHOW_PROGRESS);
Message msg = mHandler.obtainMessage(FADE_OUT);
if (timeout != 0) {
mHandler.removeMessages(FADE_OUT);
mHandler.sendMessageDelayed(msg, timeout);
public boolean isShowing() {
public void hide() {
if (mAnchor == null)
if (mShowing) {
mHandler.removeMessages(SHOW_PROGRESS);
mWindowManager.removeView(mDecor);
} catch (IllegalArgumentException ex) {
Log.w("MediaController", "already removed");
mShowing =
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case FADE_OUT:
case SHOW_PROGRESS:
pos = setProgress();
if (!mDragging && mShowing
&& mPlayer.isPlaying()) {
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000 - (pos % 1000));
private String stringForTime(int timeMs) {
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours & 0) {
return mFormatter.format("%d:d:d", hours, minutes, seconds)
.toString();
return mFormatter.format("d:d", minutes, seconds).toString();
private int setProgress() {
if (mPlayer == null || mDragging) {
int position = mPlayer.getCurrentPosition();
int duration = mPlayer.getDuration();
if (mProgress != null) {
if (duration & 0) {
// use long to avoid overflow
long pos = 1000L * position /
mProgress.setProgress((int) pos);
int percent = mPlayer.getBufferPercentage();
mProgress.setSecondaryProgress(percent * 10);
if (mEndTime != null)
mEndTime.setText(stringForTime(duration));
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime(position));
public boolean onTouchEvent(MotionEvent event) {
show(sDefaultTimeout);
public boolean onTrackballEvent(MotionEvent ev) {
show(sDefaultTimeout);
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
if (event.getRepeatCount() == 0
&& event.isDown()
&& (keyCode ==
KeyEvent.KEYCODE_HEADSETHOOK
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode ==
KeyEvent.KEYCODE_SPACE)) {
doPauseResume();
show(sDefaultTimeout);
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {
if (mPlayer.isPlaying()) {
mPlayer.pause();
updatePausePlay();
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
// don't show the controls for volume adjustment
return super.dispatchKeyEvent(event);
} else if (keyCode == KeyEvent.KEYCODE_BACK
|| keyCode == KeyEvent.KEYCODE_MENU) {
show(sDefaultTimeout);
return super.dispatchKeyEvent(event);
private View.OnClickListener mPauseListener = new
View.OnClickListener() {
public void onClick(View v) {
doPauseResume();
show(sDefaultTimeout);
private void updatePausePlay() {
if (mRoot == null)
ImageButton button = (ImageButton) mRoot
.findViewById(com.android.internal.R.id.pause);
if (button == null)
if (mPlayer.isPlaying()) {
.setImageResource(com.android.internal.R.drawable.ic_media_pause);
.setImageResource(com.android.internal.R.drawable.ic_media_play);
private void doPauseResume() {
if (mPlayer.isPlaying()) {
mPlayer.pause();
mPlayer.start();
updatePausePlay();
// There are two scenarios that can trigger the seekbar listener to
// The first is the user using the touchpad to adjust the posititon
// seekbar's thumb. In this case onStartTrackingTouch is called
followed by
// a number of onProgressChanged notifications, concluded by
// onStopTrackingTouch.
// We're setting the field "mDragging" to true for the duration of
// dragging
// session to avoid jumps in the position in case of ongoing
// The second scenario involves the user operating the scroll ball,
// case there WON'T BE
onStartTrackingTouch/onStopTrackingTouch
// notifications,
// we will simply apply the updated position without suspending
// updates.
private OnSeekBarChangeListener mSeekListener = new
OnSeekBarChangeListener() {
public void onStartTrackingTouch(SeekBar bar) {
show(3600000);
mDragging =
// By removing these pending progress messages we make sure
// that a) we won't update the progress while the user
// the seekbar and b) once the user is done dragging the
// we will post one of these messages to the queue again and
// this ensures that there will be exactly one message queued
mHandler.removeMessages(SHOW_PROGRESS);
public void onProgressChanged(SeekBar bar, int progress,
boolean fromuser) {
if (!fromuser) {
// We're not interested in programmatically generated changes
// the progress bar's position.
long duration = mPlayer.getDuration();
long newposition = (duration * progress) / 1000L;
mPlayer.seekTo((int) newposition);
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime((int) newposition));
public void onStopTrackingTouch(SeekBar bar) {
mDragging =
setProgress();
updatePausePlay();
show(sDefaultTimeout);
// Ensure that progress is properly updated in the future,
// the call to show() does not guarantee this because it is a
// no-op if we are already showing.
mHandler.sendEmptyMessage(SHOW_PROGRESS);
public void setEnabled(boolean enabled) {
if (mPauseButton != null) {
mPauseButton.setEnabled(enabled);
if (mFfwdButton != null) {
mFfwdButton.setEnabled(enabled);
if (mRewButton != null) {
mRewButton.setEnabled(enabled);
if (mNextButton != null) {
mNextButton.setEnabled(enabled &&
mNextListener != null);
if (mPrevButton != null) {
mPrevButton.setEnabled(enabled &&
mPrevListener != null);
if (mProgress != null) {
mProgress.setEnabled(enabled);
super.setEnabled(enabled);
private View.OnClickListener mRewListener = new
View.OnClickListener() {
public void onClick(View v) {
int pos = mPlayer.getCurrentPosition();
pos -= 5000; // milliseconds
mPlayer.seekTo(pos);
setProgress();
show(sDefaultTimeout);
private View.OnClickListener mFfwdListener = new
View.OnClickListener() {
public void onClick(View v) {
int pos = mPlayer.getCurrentPosition();
pos += 15000; // milliseconds
mPlayer.seekTo(pos);
setProgress();
show(sDefaultTimeout);
private void installPrevNextListeners() {
if (mNextButton != null) {
mNextButton.setOnClickListener(mNextListener);
mNextButton.setEnabled(mNextListener != null);
if (mPrevButton != null) {
mPrevButton.setOnClickListener(mPrevListener);
mPrevButton.setEnabled(mPrevListener != null);
public void setPrevNextListeners(View.OnClickListener next,
View.OnClickListener prev) {
mNextListener =
mPrevListener =
mListenersSet =
if (mRoot != null) {
installPrevNextListeners();
if (mNextButton != null &&
!mFromXml) {
mNextButton.setVisibility(View.VISIBLE);
if (mPrevButton != null &&
!mFromXml) {
mPrevButton.setVisibility(View.VISIBLE);
public interface MediaPlayerControl {
void start();
void pause();
int getDuration();
int getCurrentPosition();
void seekTo(int pos);
boolean isPlaying();
int getBufferPercentage();
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。Android MediaController - 追求幸福 - ITeye技术网站
博客分类:
android 的mediaPlayer 有自带的MediaControl.我们不比自己重写这个控件:
A view containing controls for a MediaPlayer. Typically contains the buttons like "Play/Pause", "Rewind", "Fast Forward" and a progress slider. It takes care of synchronizing the controls with the state of the MediaPlayer.
The way to use this class is to instantiate it programatically. The MediaController will create a default set of controls and put them in a window floating above your application. Specifically, the controls will float above the view specified with setAnchorView(). The window will disappear if left idle for three seconds and reappear when the user touches the anchor view.
Functions like show() and hide() have no effect when MediaController is created in an xml layout. MediaController will hide and show the buttons according to these rules:
The "previous" and "next" buttons are hidden until setPrevNextListeners() has been called
The "previous" and "next" buttons are visible but disabled if setPrevNextListeners() was called with null listeners
The "rewind" and "fastforward" buttons are shown unless requested otherwise by using the MediaController(Context, boolean) constructor with the boolean set to false
package android.
import android.content.C
import android.graphics.PixelF
import android.media.AudioM
import android.os.H
import android.os.M
import android.util.AttributeS
import android.util.L
import android.view.G
import android.view.KeyE
import android.view.LayoutI
import android.view.MotionE
import android.view.V
import android.view.ViewG
import android.view.W
import android.view.WindowM
import android.widget.SeekBar.OnSeekBarChangeL
import com.android.internal.policy.PolicyM
import java.util.F
import java.util.L
* A view containing controls for a MediaPlayer. Typically contains the buttons
* like "Play/Pause", "Rewind", "Fast Forward" and a progress slider. It takes
* care of synchronizing the controls with the state of the MediaPlayer.
* The way to use this class is to instantiate it programatically. The
* MediaController will create a default set of controls and put them in a
* window floating above your application. Specifically, the controls will float
* above the view specified with setAnchorView(). The window will disappear if
* left idle for three seconds and reappear when the user touches the anchor
* Functions like show() and hide() have no effect when MediaController is
* created in an xml layout.
* MediaController will hide and show the buttons according to these rules:
* &li&The "previous" and "next" buttons are hidden until setPrevNextListeners()
* has been called
* &li&The "previous" and "next" buttons are visible but disabled if
* setPrevNextListeners() was called with null listeners
* &li&The "rewind" and "fastforward" buttons are shown unless requested
* otherwise by using the MediaController(Context, boolean) constructor with the
* boolean set to false
*/
public class MediaController extends FrameLayout {
private MediaPlayerControl mP
private Context mC
private View mA
private View mR
private WindowManager mWindowM
private Window mW
private View mD
private ProgressBar mP
private TextView mEndTime, mCurrentT
private boolean mS
private boolean mD
private static final int sDefaultTimeout = 3000;
private static final int FADE_OUT = 1;
private static final int SHOW_PROGRESS = 2;
private boolean mUseFastF
private boolean mFromX
private boolean mListenersS
private View.OnClickListener mNextListener, mPrevL
StringBuilder mFormatB
Formatter mF
private ImageButton mPauseB
private ImageButton mFfwdB
private ImageButton mRewB
private ImageButton mNextB
private ImageButton mPrevB
public MediaController(Context context, AttributeSet attrs) {
super(context, attrs);
mContext =
mUseFastForward =
mFromXml =
public void onFinishInflate() {
if (mRoot != null)
initControllerView(mRoot);
}
/×在这里设置是否使用FastForward而不是NuseFastForward=false时使用&& Next/Prevouse按钮所以我们在实例化MediaControl是调用这个构造函数,并且 useFastForward=false×/
public MediaController(Context context, boolean useFastForward) {
super(context);
mContext =
mUseFastForward = useFastF
initFloatingWindow();
public MediaController(Context context) {
super(context);
mContext =
mUseFastForward =
initFloatingWindow();
private void initFloatingWindow() {
mWindowManager = (WindowManager) mContext.getSystemService("window");
mWindow = PolicyManager.makeNewWindow(mContext);
mWindow.setWindowManager(mWindowManager, null, null);
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
mDecor = mWindow.getDecorView();
mDecor.setOnTouchListener(mTouchListener);
mWindow.setContentView(this);
mWindow.setBackgroundDrawableResource(android.R.color.transparent);
// While the media controller is up, the volume control keys should
// affect the media stream type
mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC);
setFocusable(true);
setFocusableInTouchMode(true);
setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
requestFocus();
private OnTouchListener mTouchListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mShowing) {
public void setMediaPlayer(MediaPlayerControl player) {
updatePausePlay();
* Set the view that acts as the anchor for the control view. This can for
* example be a VideoView, or your Activity's main view.
* @param view
*&&&&&&&&&&& The view to which to anchor the controller when it is visible.
public void setAnchorView(View view) {
FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
removeAllViews();
View v = makeControllerView();
addView(v, frameParams);
* Create the view that holds the widgets that control playback. Derived
* classes can override this to create their own.
* @return The controller view.
* @hide This doesn't work as advertised
protected View makeControllerView() {
LayoutInflater inflate = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mRoot = inflate.inflate(com.android.internal.R.layout.media_controller,
initControllerView(mRoot);
private void initControllerView(View v) {
mPauseButton = (ImageButton) v
.findViewById(com.android.internal.R.id.pause);
if (mPauseButton != null) {
mPauseButton.requestFocus();
mPauseButton.setOnClickListener(mPauseListener);
mFfwdButton = (ImageButton) v
.findViewById(com.android.internal.R.id.ffwd);
if (mFfwdButton != null) {
mFfwdButton.setOnClickListener(mFfwdListener);
if (!mFromXml) {
mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE
: View.GONE);
mRewButton = (ImageButton) v
.findViewById(com.android.internal.R.id.rew);
if (mRewButton != null) {
mRewButton.setOnClickListener(mRewListener);
if (!mFromXml) {
mRewButton.setVisibility(mUseFastForward ? View.VISIBLE
: View.GONE);
// By default these are hidden. They will be enabled when
// setPrevNextListeners() is called
mNextButton = (ImageButton) v
.findViewById(com.android.internal.R.id.next);
if (mNextButton != null && !mFromXml && !mListenersSet) {
mNextButton.setVisibility(View.GONE);
mPrevButton = (ImageButton) v
.findViewById(com.android.internal.R.id.prev);
if (mPrevButton != null && !mFromXml && !mListenersSet) {
mPrevButton.setVisibility(View.GONE);
mProgress = (ProgressBar) v
.findViewById(com.android.internal.R.id.mediacontroller_progress);
if (mProgress != null) {
if (mProgress instanceof SeekBar) {
SeekBar seeker = (SeekBar) mP
seeker.setOnSeekBarChangeListener(mSeekListener);
mProgress.setMax(1000);
mEndTime = (TextView) v.findViewById(com.android.internal.R.id.time);
mCurrentTime = (TextView) v
.findViewById(com.android.internal.R.id.time_current);
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
installPrevNextListeners();
* Show the controller on screen. It will go away automatically after 3
* seconds of inactivity.
public void show() {
show(sDefaultTimeout);
* Show the controller on screen. It will go away automatically after
* 'timeout' milliseconds of inactivity.
* @param timeout
*&&&&&&&&&&& The timeout in milliseconds. Use 0 to show the controller
*&&&&&&&&&&& until hide() is called.
//我们可以在这里设置MediaControl显示的位置:由P.x与P.y决定
public void show(int timeout) {
if (!mShowing && mAnchor != null) {
setProgress();
int[] anchorpos = new int[2];
mAnchor.getLocationOnScreen(anchorpos);
WindowManager.LayoutParams p = new WindowManager.LayoutParams();
p.gravity = Gravity.TOP;
p.width = mAnchor.getWidth();
p.height = LayoutParams.WRAP_CONTENT;
p.y = anchorpos[1] + mAnchor.getHeight() - p.
p.format = PixelFormat.TRANSLUCENT;
p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
p.windowAnimations = 0; // android.R.style.DropDownAnimationD
mWindowManager.addView(mDecor, p);
mShowing =
updatePausePlay();
// cause the progress bar to be updated even if mShowing
// was already true. This happens, for example, if we're
// paused with the progress bar showing the user hits play.
mHandler.sendEmptyMessage(SHOW_PROGRESS);
Message msg = mHandler.obtainMessage(FADE_OUT);
if (timeout != 0) {
mHandler.removeMessages(FADE_OUT);
mHandler.sendMessageDelayed(msg, timeout);
public boolean isShowing() {
* Remove the controller from the screen.
public void hide() {
if (mAnchor == null)
if (mShowing) {
mHandler.removeMessages(SHOW_PROGRESS);
mWindowManager.removeView(mDecor);
} catch (IllegalArgumentException ex) {
Log.w("MediaController", "already removed");
mShowing =
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case FADE_OUT:
case SHOW_PROGRESS:
pos = setProgress();
if (!mDragging && mShowing && mPlayer.isPlaying()) {
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000 - (pos % 1000));
private String stringForTime(int timeMs) {
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours & 0) {
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds)
.toString();
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
private int setProgress() {
if (mPlayer == null || mDragging) {
int position = mPlayer.getCurrentPosition();
int duration = mPlayer.getDuration();
if (mProgress != null) {
if (duration & 0) {
// use long to avoid overflow
long pos = 1000L * position /
mProgress.setProgress((int) pos);
int percent = mPlayer.getBufferPercentage();
mProgress.setSecondaryProgress(percent * 10);
if (mEndTime != null)
mEndTime.setText(stringForTime(duration));
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime(position));
public boolean onTouchEvent(MotionEvent event) {
show(sDefaultTimeout);
public boolean onTrackballEvent(MotionEvent ev) {
show(sDefaultTimeout);
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
if (event.getRepeatCount() == 0
&& event.isDown()
&& (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode == KeyEvent.KEYCODE_SPACE)) {
doPauseResume();
show(sDefaultTimeout);
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {
if (mPlayer.isPlaying()) {
mPlayer.pause();
updatePausePlay();
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
// don't show the controls for volume adjustment
return super.dispatchKeyEvent(event);
} else if (keyCode == KeyEvent.KEYCODE_BACK
|| keyCode == KeyEvent.KEYCODE_MENU) {
show(sDefaultTimeout);
return super.dispatchKeyEvent(event);
private View.OnClickListener mPauseListener = new View.OnClickListener() {
public void onClick(View v) {
doPauseResume();
show(sDefaultTimeout);
private void updatePausePlay() {
if (mRoot == null)
ImageButton button = (ImageButton) mRoot
.findViewById(com.android.internal.R.id.pause);
if (button == null)
if (mPlayer.isPlaying()) {
.setImageResource(com.android.internal.R.drawable.ic_media_pause);
.setImageResource(com.android.internal.R.drawable.ic_media_play);
private void doPauseResume() {
if (mPlayer.isPlaying()) {
mPlayer.pause();
mPlayer.start();
updatePausePlay();
// There are two scenarios that can trigger the seekbar listener to trigger:
// The first is the user using the touchpad to adjust the posititon of the
// seekbar's thumb. In this case onStartTrackingTouch is called followed by
// a number of onProgressChanged notifications, concluded by
// onStopTrackingTouch.
// We're setting the field "mDragging" to true for the duration of the
// dragging
// session to avoid jumps in the position in case of ongoing playback.
// The second scenario involves the user operating the scroll ball, in this
// case there WON'T BE onStartTrackingTouch/onStopTrackingTouch
// notifications,
// we will simply apply the updated position without suspending regular
// updates.
private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
public void onStartTrackingTouch(SeekBar bar) {
show(3600000);
mDragging =
// By removing these pending progress messages we make sure
// that a) we won't update the progress while the user adjusts
// the seekbar and b) once the user is done dragging the thumb
// we will post one of these messages to the queue again and
// this ensures that there will be exactly one message queued up.
mHandler.removeMessages(SHOW_PROGRESS);
public void onProgressChanged(SeekBar bar, int progress,
boolean fromuser) {
if (!fromuser) {
// We're not interested in programmatically generated changes to
// the progress bar's position.
long duration = mPlayer.getDuration();
long newposition = (duration * progress) / 1000L;
mPlayer.seekTo((int) newposition);
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime((int) newposition));
public void onStopTrackingTouch(SeekBar bar) {
mDragging =
setProgress();
updatePausePlay();
show(sDefaultTimeout);
// Ensure that progress is properly updated in the future,
// the call to show() does not guarantee this because it is a
// no-op if we are already showing.
mHandler.sendEmptyMessage(SHOW_PROGRESS);
public void setEnabled(boolean enabled) {
if (mPauseButton != null) {
mPauseButton.setEnabled(enabled);
if (mFfwdButton != null) {
mFfwdButton.setEnabled(enabled);
if (mRewButton != null) {
mRewButton.setEnabled(enabled);
if (mNextButton != null) {
mNextButton.setEnabled(enabled && mNextListener != null);
if (mPrevButton != null) {
mPrevButton.setEnabled(enabled && mPrevListener != null);
if (mProgress != null) {
mProgress.setEnabled(enabled);
super.setEnabled(enabled);
private View.OnClickListener mRewListener = new View.OnClickListener() {
public void onClick(View v) {
int pos = mPlayer.getCurrentPosition();
pos -= 5000; // milliseconds
mPlayer.seekTo(pos);
setProgress();
show(sDefaultTimeout);
private View.OnClickListener mFfwdListener = new View.OnClickListener() {
public void onClick(View v) {
int pos = mPlayer.getCurrentPosition();
pos += 15000; // milliseconds
mPlayer.seekTo(pos);
setProgress();
show(sDefaultTimeout);
private void installPrevNextListeners() {
if (mNextButton != null) {
mNextButton.setOnClickListener(mNextListener);
mNextButton.setEnabled(mNextListener != null);
if (mPrevButton != null) {
mPrevButton.setOnClickListener(mPrevListener);
mPrevButton.setEnabled(mPrevListener != null);
public void setPrevNextListeners(View.OnClickListener next,
View.OnClickListener prev) {
mNextListener =
mPrevListener =
mListenersSet =
if (mRoot != null) {
installPrevNextListeners();
if (mNextButton != null && !mFromXml) {
mNextButton.setVisibility(View.VISIBLE);
if (mPrevButton != null && !mFromXml) {
mPrevButton.setVisibility(View.VISIBLE);
public interface MediaPlayerControl {
void start();
void pause();
int getDuration();
int getCurrentPosition();
void seekTo(int pos);
boolean isPlaying();
int getBufferPercentage();
浏览 10000
麻烦问下,这个如何自定义布局.我之前自定义布局是这样做的:先看懂它原来的代码,然后把它相关的代码复制到自己的工程里面变成MyMediaControl,然后修改相关的XML,在相对应的地方模仿原来的方式增加一些监听事件
浏览: 581117 次
来自: 南昌
mark一下,学习了
问题解决,谢谢。

我要回帖

更多关于 android controller 的文章

 

随机推荐