19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.media.AudioManager; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MotionEvent; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Window; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager; 348a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 358a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.SeekBar.OnSeekBarChangeListener; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.policy.PolicyManager; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Formatter; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Locale; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A view containing controls for a MediaPlayer. Typically contains the 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * buttons like "Play/Pause", "Rewind", "Fast Forward" and a progress 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * slider. It takes care of synchronizing the controls with the state 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the MediaPlayer. 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The way to use this class is to instantiate it programatically. 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The MediaController will create a default set of controls 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and put them in a window floating above your application. Specifically, 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the controls will float above the view specified with setAnchorView(). 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The window will disappear if left idle for three seconds and reappear 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the user touches the anchor view. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Functions like show() and hide() have no effect when MediaController 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is created in an xml layout. 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MediaController will hide and 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * show the buttons according to these rules: 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> The "previous" and "next" buttons are hidden until setPrevNextListeners() 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been called 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> The "previous" and "next" buttons are visible but disabled if 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * setPrevNextListeners() was called with null listeners 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> The "rewind" and "fastforward" buttons are shown unless requested 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise by using the MediaController(Context, boolean) constructor 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with the boolean set to false 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class MediaController extends FrameLayout { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MediaPlayerControl mPlayer; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mAnchor; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mRoot; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WindowManager mWindowManager; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Window mWindow; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mDecor; 8085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang private WindowManager.LayoutParams mDecorLayoutParams; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ProgressBar mProgress; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private TextView mEndTime, mCurrentTime; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mShowing; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mDragging; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int sDefaultTimeout = 3000; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int FADE_OUT = 1; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SHOW_PROGRESS = 2; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mUseFastForward; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFromXml; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mListenersSet; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View.OnClickListener mNextListener, mPrevListener; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder mFormatBuilder; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Formatter mFormatter; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mPauseButton; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mFfwdButton; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mRewButton; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mNextButton; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mPrevButton; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MediaController(Context context, AttributeSet attrs) { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRoot = this; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUseFastForward = true; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFromXml = true; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onFinishInflate() { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRoot != null) 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initControllerView(mRoot); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MediaController(Context context, boolean useFastForward) { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUseFastForward = useFastForward; 11802dd17da3685652b5235ca48bd6882e65997434aChih-Chung Chang initFloatingWindowLayout(); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initFloatingWindow(); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MediaController(Context context) { 12302dd17da3685652b5235ca48bd6882e65997434aChih-Chung Chang this(context, true); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initFloatingWindow() { 127ef367529f9c7a538d74599b37b49ac309d0a8d8cChristian Mehlmauer mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow = PolicyManager.makeNewWindow(mContext); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.setWindowManager(mWindowManager, null, null); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.requestFeature(Window.FEATURE_NO_TITLE); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDecor = mWindow.getDecorView(); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDecor.setOnTouchListener(mTouchListener); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.setContentView(this); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.setBackgroundDrawableResource(android.R.color.transparent); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // While the media controller is up, the volume control keys should 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // affect the media stream type 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusable(true); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusableInTouchMode(true); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestFocus(); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // Allocate and initialize the static parts of mDecorLayoutParams. Must 14785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // also call updateFloatingWindowLayout() to fill in the dynamic parts 14885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // (y and width) before mDecorLayoutParams can be used. 14985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang private void initFloatingWindowLayout() { 15085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mDecorLayoutParams = new WindowManager.LayoutParams(); 15185d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang WindowManager.LayoutParams p = mDecorLayoutParams; 15285d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.gravity = Gravity.TOP; 15385d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.height = LayoutParams.WRAP_CONTENT; 15485d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.x = 0; 15585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.format = PixelFormat.TRANSLUCENT; 15685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 15785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 15885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 15985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; 16085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.token = null; 16185d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.windowAnimations = 0; // android.R.style.DropDownAnimationDown; 16285d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 16385d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang 16485d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // Update the dynamic parts of mDecorLayoutParams 16585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // Must be called with mAnchor != NULL. 16685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang private void updateFloatingWindowLayout() { 16785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang int [] anchorPos = new int[2]; 16885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mAnchor.getLocationOnScreen(anchorPos); 16985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang 17085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang WindowManager.LayoutParams p = mDecorLayoutParams; 17185d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.width = mAnchor.getWidth(); 17285d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.y = anchorPos[1] + mAnchor.getHeight(); 17385d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 17485d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang 17585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // This is called whenever mAnchor's layout bound changes 17685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang private OnLayoutChangeListener mLayoutChangeListener = 17785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang new OnLayoutChangeListener() { 17885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang public void onLayoutChange(View v, int left, int top, int right, 17985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang int bottom, int oldLeft, int oldTop, int oldRight, 18085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang int oldBottom) { 18185d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang updateFloatingWindowLayout(); 18285d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang if (mShowing) { 18385d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mWindowManager.updateViewLayout(mDecor, mDecorLayoutParams); 18485d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 18585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 18685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang }; 18785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnTouchListener mTouchListener = new OnTouchListener() { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouch(View v, MotionEvent event) { 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getAction() == MotionEvent.ACTION_DOWN) { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShowing) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hide(); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMediaPlayer(MediaPlayerControl player) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer = player; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the view that acts as the anchor for the control view. 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This can for example be a VideoView, or your Activity's main view. 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param view The view to which to anchor the controller when it is visible. 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAnchorView(View view) { 21085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang if (mAnchor != null) { 21185d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mAnchor.removeOnLayoutChangeListener(mLayoutChangeListener); 21285d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchor = view; 21485d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang if (mAnchor != null) { 21585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mAnchor.addOnLayoutChangeListener(mLayoutChangeListener); 21685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams( 219980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy ViewGroup.LayoutParams.MATCH_PARENT, 220980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy ViewGroup.LayoutParams.MATCH_PARENT 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeAllViews(); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View v = makeControllerView(); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addView(v, frameParams); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create the view that holds the widgets that control playback. 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Derived classes can override this to create their own. 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The controller view. 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide This doesn't work as advertised 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected View makeControllerView() { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LayoutInflater inflate = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRoot = inflate.inflate(com.android.internal.R.layout.media_controller, null); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initControllerView(mRoot); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRoot; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initControllerView(View v) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPauseButton = (ImageButton) v.findViewById(com.android.internal.R.id.pause); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPauseButton != null) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPauseButton.requestFocus(); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPauseButton.setOnClickListener(mPauseListener); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFfwdButton = (ImageButton) v.findViewById(com.android.internal.R.id.ffwd); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFfwdButton != null) { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFfwdButton.setOnClickListener(mFfwdListener); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFromXml) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRewButton = (ImageButton) v.findViewById(com.android.internal.R.id.rew); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRewButton != null) { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRewButton.setOnClickListener(mRewListener); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFromXml) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // By default these are hidden. They will be enabled when setPrevNextListeners() is called 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton = (ImageButton) v.findViewById(com.android.internal.R.id.next); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextButton != null && !mFromXml && !mListenersSet) { 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setVisibility(View.GONE); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton = (ImageButton) v.findViewById(com.android.internal.R.id.prev); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPrevButton != null && !mFromXml && !mListenersSet) { 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setVisibility(View.GONE); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress = (ProgressBar) v.findViewById(com.android.internal.R.id.mediacontroller_progress); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProgress != null) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProgress instanceof SeekBar) { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SeekBar seeker = (SeekBar) mProgress; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project seeker.setOnSeekBarChangeListener(mSeekListener); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress.setMax(1000); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEndTime = (TextView) v.findViewById(com.android.internal.R.id.time); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentTime = (TextView) v.findViewById(com.android.internal.R.id.time_current); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFormatBuilder = new StringBuilder(); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFormatter = new Formatter(mFormatBuilder, Locale.getDefault()); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project installPrevNextListeners(); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Show the controller on screen. It will go away 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * automatically after 3 seconds of inactivity. 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void show() { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 302c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen * Disable pause or seek buttons if the stream cannot be paused or seeked. 303c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen * This requires the control interface to be a MediaPlayerControlExt 304c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen */ 305c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen private void disableUnsupportedButtons() { 306c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen try { 307c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen if (mPauseButton != null && !mPlayer.canPause()) { 308c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mPauseButton.setEnabled(false); 309c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 310c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen if (mRewButton != null && !mPlayer.canSeekBackward()) { 311c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mRewButton.setEnabled(false); 312c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 313c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen if (mFfwdButton != null && !mPlayer.canSeekForward()) { 314c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mFfwdButton.setEnabled(false); 315c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 316c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } catch (IncompatibleClassChangeError ex) { 317c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen // We were given an old version of the interface, that doesn't have 318c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen // the canPause/canSeekXYZ methods. This is OK, it just means we 319c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen // assume the media can be paused and seeked, and so we don't disable 320c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen // the buttons. 321c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 322c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 323c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen 324c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen /** 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Show the controller on screen. It will go away 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * automatically after 'timeout' milliseconds of inactivity. 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param timeout The timeout in milliseconds. Use 0 to show 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the controller until hide() is called. 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void show(int timeout) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mShowing && mAnchor != null) { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(); 333d701e020769b7cc6dd492eadcb09083578074ee0Marco Nelissen if (mPauseButton != null) { 334d701e020769b7cc6dd492eadcb09083578074ee0Marco Nelissen mPauseButton.requestFocus(); 335d701e020769b7cc6dd492eadcb09083578074ee0Marco Nelissen } 336c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen disableUnsupportedButtons(); 33785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang updateFloatingWindowLayout(); 33885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mWindowManager.addView(mDecor, mDecorLayoutParams); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowing = true; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cause the progress bar to be updated even if mShowing 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // was already true. This happens, for example, if we're 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // paused with the progress bar showing the user hits play. 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendEmptyMessage(SHOW_PROGRESS); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = mHandler.obtainMessage(FADE_OUT); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (timeout != 0) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(FADE_OUT); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessageDelayed(msg, timeout); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShowing() { 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mShowing; 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove the controller from the screen. 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void hide() { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAnchor == null) 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShowing) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(SHOW_PROGRESS); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowManager.removeView(mDecor); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException ex) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("MediaController", "already removed"); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowing = false; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Handler mHandler = new Handler() { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pos; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FADE_OUT: 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hide(); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SHOW_PROGRESS: 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos = setProgress(); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDragging && mShowing && mPlayer.isPlaying()) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg = obtainMessage(SHOW_PROGRESS); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessageDelayed(msg, 1000 - (pos % 1000)); 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String stringForTime(int timeMs) { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int totalSeconds = timeMs / 1000; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int seconds = totalSeconds % 60; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int minutes = (totalSeconds / 60) % 60; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int hours = totalSeconds / 3600; 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFormatBuilder.setLength(0); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hours > 0) { 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString(); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFormatter.format("%02d:%02d", minutes, seconds).toString(); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int setProgress() { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlayer == null || mDragging) { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = mPlayer.getCurrentPosition(); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int duration = mPlayer.getDuration(); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProgress != null) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (duration > 0) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // use long to avoid overflow 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long pos = 1000L * position / duration; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress.setProgress( (int) pos); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int percent = mPlayer.getBufferPercentage(); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress.setSecondaryProgress(percent * 10); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEndTime != null) 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEndTime.setText(stringForTime(duration)); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrentTime != null) 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentTime.setText(stringForTime(position)); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return position; 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTrackballEvent(MotionEvent ev) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int keyCode = event.getKeyCode(); 4504d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown final boolean uniqueDown = event.getRepeatCount() == 0 4514d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown && event.getAction() == KeyEvent.ACTION_DOWN; 4524d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK 4534d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE 4544d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown || keyCode == KeyEvent.KEYCODE_SPACE) { 4554d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (uniqueDown) { 4564d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown doPauseResume(); 4574d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown show(sDefaultTimeout); 4584d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (mPauseButton != null) { 4594d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown mPauseButton.requestFocus(); 4604d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } 4614d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } 4624d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown return true; 4634d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) { 4644d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (uniqueDown && !mPlayer.isPlaying()) { 4654d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown mPlayer.start(); 4664d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown updatePausePlay(); 4674d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown show(sDefaultTimeout); 468d701e020769b7cc6dd492eadcb09083578074ee0Marco Nelissen } 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4704d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP 4714d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) { 4724d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (uniqueDown && mPlayer.isPlaying()) { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.pause(); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 4754d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown show(sDefaultTimeout); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4784d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 479b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP 48096ac720117979ab0507d8760f49076a0a1e3bfb8bxu || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE 48196ac720117979ab0507d8760f49076a0a1e3bfb8bxu || keyCode == KeyEvent.KEYCODE_CAMERA) { 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't show the controls for volume adjustment 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) { 4854d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (uniqueDown) { 4864d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown hide(); 4874d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } 488105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project return true; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4904d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown 4914d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown show(sDefaultTimeout); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View.OnClickListener mPauseListener = new View.OnClickListener() { 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onClick(View v) { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doPauseResume(); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updatePausePlay() { 503c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen if (mRoot == null || mPauseButton == null) 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlayer.isPlaying()) { 507c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mPauseButton.setImageResource(com.android.internal.R.drawable.ic_media_pause); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 509c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mPauseButton.setImageResource(com.android.internal.R.drawable.ic_media_play); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void doPauseResume() { 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlayer.isPlaying()) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.pause(); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.start(); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5220de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // There are two scenarios that can trigger the seekbar listener to trigger: 5230de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // 5240de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // The first is the user using the touchpad to adjust the posititon of the 5250de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // seekbar's thumb. In this case onStartTrackingTouch is called followed by 5260de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // a number of onProgressChanged notifications, concluded by onStopTrackingTouch. 5270de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // We're setting the field "mDragging" to true for the duration of the dragging 5280de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // session to avoid jumps in the position in case of ongoing playback. 5290de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // 5300de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // The second scenario involves the user operating the scroll ball, in this 5310de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // case there WON'T BE onStartTrackingTouch/onStopTrackingTouch notifications, 5320de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // we will simply apply the updated position without suspending regular updates. 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() { 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onStartTrackingTouch(SeekBar bar) { 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(3600000); 5360de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5370de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mDragging = true; 5380de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5390de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // By removing these pending progress messages we make sure 5400de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // that a) we won't update the progress while the user adjusts 5410de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // the seekbar and b) once the user is done dragging the thumb 5420de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // we will post one of these messages to the queue again and 5430de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // this ensures that there will be exactly one message queued up. 5440de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mHandler.removeMessages(SHOW_PROGRESS); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5460de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5470de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { 5480de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber if (!fromuser) { 5490de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // We're not interested in programmatically generated changes to 5500de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // the progress bar's position. 5510de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber return; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5530de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5540de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber long duration = mPlayer.getDuration(); 5550de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber long newposition = (duration * progress) / 1000L; 5560de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mPlayer.seekTo( (int) newposition); 5570de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber if (mCurrentTime != null) 5580de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mCurrentTime.setText(stringForTime( (int) newposition)); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5600de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onStopTrackingTouch(SeekBar bar) { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDragging = false; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 5660de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5670de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // Ensure that progress is properly updated in the future, 5680de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // the call to show() does not guarantee this because it is a 5690de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // no-op if we are already showing. 5700de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mHandler.sendEmptyMessage(SHOW_PROGRESS); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setEnabled(boolean enabled) { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPauseButton != null) { 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPauseButton.setEnabled(enabled); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFfwdButton != null) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFfwdButton.setEnabled(enabled); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRewButton != null) { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRewButton.setEnabled(enabled); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextButton != null) { 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setEnabled(enabled && mNextListener != null); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPrevButton != null) { 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setEnabled(enabled && mPrevListener != null); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProgress != null) { 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress.setEnabled(enabled); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 594c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen disableUnsupportedButtons(); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setEnabled(enabled); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5988a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 5998a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 6008a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityEvent(event); 6018a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov event.setClassName(MediaController.class.getName()); 6028a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 6038a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 6048a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 6058a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 6068a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityNodeInfo(info); 6078a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov info.setClassName(MediaController.class.getName()); 6088a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 6098a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View.OnClickListener mRewListener = new View.OnClickListener() { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onClick(View v) { 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pos = mPlayer.getCurrentPosition(); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos -= 5000; // milliseconds 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.seekTo(pos); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View.OnClickListener mFfwdListener = new View.OnClickListener() { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onClick(View v) { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pos = mPlayer.getCurrentPosition(); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos += 15000; // milliseconds 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.seekTo(pos); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void installPrevNextListeners() { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextButton != null) { 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setOnClickListener(mNextListener); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setEnabled(mNextListener != null); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPrevButton != null) { 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setOnClickListener(mPrevListener); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setEnabled(mPrevListener != null); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setPrevNextListeners(View.OnClickListener next, View.OnClickListener prev) { 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextListener = next; 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevListener = prev; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListenersSet = true; 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRoot != null) { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project installPrevNextListeners(); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextButton != null && !mFromXml) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setVisibility(View.VISIBLE); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPrevButton != null && !mFromXml) { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setVisibility(View.VISIBLE); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface MediaPlayerControl { 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void start(); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void pause(); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int getDuration(); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int getCurrentPosition(); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void seekTo(int pos); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isPlaying(); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int getBufferPercentage(); 669c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen boolean canPause(); 670c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen boolean canSeekBackward(); 671c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen boolean canSeekForward(); 672c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 674