Most visited

Recently visited

TransportMediator

public class TransportMediator
extends TransportController

java.lang.Object
   ↳ android.support.v4.media.TransportController
     ↳ android.support.v4.media.TransportMediator


助手实现媒体传输控制(播放,暂停,跳过和其他媒体操作)。 照顾重要事件和高级功能,如RemoteControlClient 该课程旨在作为交通控制(无论是屏幕控制,硬件按钮,遥控器)还是实际玩家之间的中介。 玩家由一个TransportPerformer代表,必须提供给该课程。 希望控制和显示播放器状态的屏幕控件应通过调用TransportController界面来完成。

这是一个简单但相当完整的围绕此课程构建的视频播放器示例。 请注意,此处使用的MediaController类不是标准Android框架中包含的类,而是自定义实现。 真正的应用程序通常会实现自己的传输控制,或者您可以将实现从Support4Demos中复制出来。

import android.support.v4.media.TransportMediator;
import android.support.v4.media.TransportPerformer;
import com.example.android.supportv4.R;

import android.app.ActionBar;
import android.content.Context;
import android.media.MediaPlayer;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.VideoView;

public class TransportControllerActivity extends Activity {

    /**
     * TODO: Set the path variable to a streaming video URL or a local media
     * file path.
     */
    private Content mContent;
    private TransportMediator mTransportMediator;
    private MediaController mMediaController;

    /**
     * Handle actions from on-screen media controls.  Most of these are simple re-directs
     * to the VideoView; some we need to capture to update our state.
     */
    TransportPerformer mTransportPerformer = new TransportPerformer() {
        @Override public void onStart() {
            mContent.start();
        }

        @Override public void onStop() {
            mContent.pause();
        }

        @Override public void onPause() {
            mContent.pause();
        }

        @Override public long onGetDuration() {
            return mContent.getDuration();
        }

        @Override public long onGetCurrentPosition() {
            return mContent.getCurrentPosition();
        }

        @Override public void onSeekTo(long pos) {
            mContent.seekTo((int)pos);
        }

        @Override public boolean onIsPlaying() {
            return mContent.isPlaying();
        }

        @Override public int onGetBufferPercentage() {
            return mContent.getBufferPercentage();
        }

        @Override public int onGetTransportControlFlags() {
            int flags = TransportMediator.FLAG_KEY_MEDIA_PLAY
                    | TransportMediator.FLAG_KEY_MEDIA_PLAY_PAUSE
                    | TransportMediator.FLAG_KEY_MEDIA_STOP;
            if (mContent.canPause()) {
                flags |= TransportMediator.FLAG_KEY_MEDIA_PAUSE;
            }
            if (mContent.canSeekBackward()) {
                flags |= TransportMediator.FLAG_KEY_MEDIA_REWIND;
            }
            if (mContent.canSeekForward()) {
                flags |= TransportMediator.FLAG_KEY_MEDIA_FAST_FORWARD;
            }
            return flags;
        }
    };

    /**
     * This is the actual video player.  It is the top-level content of
     * the activity's view hierarchy, going under the status bar and nav
     * bar areas.
     */
    public static class Content extends VideoView implements
            View.OnSystemUiVisibilityChangeListener, View.OnClickListener,
            ActionBar.OnMenuVisibilityListener, MediaPlayer.OnPreparedListener,
            MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
        Activity mActivity;
        TransportMediator mTransportMediator;
        MediaController mMediaController;
        boolean mAddedMenuListener;
        boolean mMenusOpen;
        boolean mPaused;
        boolean mNavVisible;
        int mLastSystemUiVis;

        Runnable mNavHider = new Runnable() {
            @Override public void run() {
                setNavVisibility(false);
            }
        };

        Runnable mProgressUpdater = new Runnable() {
            @Override public void run() {
                mMediaController.updateProgress();
                getHandler().postDelayed(this, 1000);
            }
        };

        public Content(Context context, AttributeSet attrs) {
            super(context, attrs);
            setOnSystemUiVisibilityChangeListener(this);
            setOnClickListener(this);
            setOnPreparedListener(this);
            setOnCompletionListener(this);
            setOnErrorListener(this);
        }

        public void init(Activity activity, TransportMediator transportMediator,
                MediaController mediaController) {
            // This called by the containing activity to supply the surrounding
            // state of the video player that it will interact with.
            mActivity = activity;
            mTransportMediator = transportMediator;
            mMediaController = mediaController;
            pause();
        }

        @Override protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            if (mActivity != null) {
                mAddedMenuListener = true;
                mActivity.getActionBar().addOnMenuVisibilityListener(this);
            }
        }

        @Override protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            if (mAddedMenuListener) {
                mActivity.getActionBar().removeOnMenuVisibilityListener(this);
            }
            mNavVisible = false;
        }

        @Override public void onSystemUiVisibilityChange(int visibility) {
            // Detect when we go out of nav-hidden mode, to clear our state
            // back to having the full UI chrome up.  Only do this when
            // the state is changing and nav is no longer hidden.
            int diff = mLastSystemUiVis ^ visibility;
            mLastSystemUiVis = visibility;
            if ((diff&SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
                    && (visibility&SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
                setNavVisibility(true);
            }
        }

        @Override protected void onWindowVisibilityChanged(int visibility) {
            super.onWindowVisibilityChanged(visibility);

            // When we become visible or invisible, play is paused.
            pause();
        }

        @Override public void onClick(View v) {
            // Clicking anywhere makes the navigation visible.
            setNavVisibility(true);
        }

        @Override public void onMenuVisibilityChanged(boolean isVisible) {
            mMenusOpen = isVisible;
            setNavVisibility(true);
        }

        @Override
        public void onPrepared(MediaPlayer mp) {
            mMediaController.setEnabled(true);
        }

        @Override
        public void onCompletion(MediaPlayer mp) {
            mTransportMediator.pausePlaying();
            pause();
        }

        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            mTransportMediator.pausePlaying();
            pause();
            return false;
        }

        @Override public void start() {
            super.start();
            mPaused = false;
            setKeepScreenOn(true);
            setNavVisibility(true);
            mMediaController.refresh();
            scheduleProgressUpdater();
        }

        @Override public void pause() {
            super.pause();
            mPaused = true;
            setKeepScreenOn(false);
            setNavVisibility(true);
            mMediaController.refresh();
            scheduleProgressUpdater();
        }

        void scheduleProgressUpdater() {
            Handler h = getHandler();
            if (h != null) {
                if (mNavVisible && !mPaused) {
                    h.removeCallbacks(mProgressUpdater);
                    h.post(mProgressUpdater);
                } else {
                    h.removeCallbacks(mProgressUpdater);
                }
            }
        }

        void setNavVisibility(boolean visible) {
            int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | SYSTEM_UI_FLAG_LAYOUT_STABLE;
            if (!visible) {
                newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN
                        | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
            }

            // If we are now visible, schedule a timer for us to go invisible.
            if (visible) {
                Handler h = getHandler();
                if (h != null) {
                    h.removeCallbacks(mNavHider);
                    if (!mMenusOpen && !mPaused) {
                        // If the menus are open or play is paused, we will not auto-hide.
                        h.postDelayed(mNavHider, 3000);
                    }
                }
            }

            // Set the new desired visibility.
            setSystemUiVisibility(newVis);
            mNavVisible = visible;
            mMediaController.setVisibility(visible ? VISIBLE : INVISIBLE);
            scheduleProgressUpdater();
        }
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.videoview);

        // Find the video player in our UI.
        mContent = (Content) findViewById(R.id.content);

        // Create transport controller to control video, giving the callback
        // interface to receive actions from.
        mTransportMediator = new TransportMediator(this, mTransportPerformer);

        // Create and initialize the media control UI.
        mMediaController = (MediaController) findViewById(R.id.media_controller);
        mMediaController.setMediaPlayer(mTransportMediator);

        // We're just playing a built-in demo video.
        mContent.init(this, mTransportMediator, mMediaController);
        mContent.setVideoURI(Uri.parse("android.resource://" + getPackageName() +
                "/" + R.raw.videoviewdemo));
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        // We first dispatch keys to the transport controller -- we want it
        // to get to consume any media keys rather than letting whoever has focus
        // in the view hierarchy to potentially eat it.
        if (mTransportMediator.dispatchKeyEvent(event)) {
            return true;
        }

        return super.dispatchKeyEvent(event);
    }
}

Summary

Constants

int FLAG_KEY_MEDIA_FAST_FORWARD

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_FAST_FORWARD RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD的同义词

int FLAG_KEY_MEDIA_NEXT

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_NEXT RemoteControlClient.FLAG_KEY_MEDIA_NEXT的同义词

int FLAG_KEY_MEDIA_PAUSE

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PAUSE RemoteControlClient.FLAG_KEY_MEDIA_PAUSE的同义词

int FLAG_KEY_MEDIA_PLAY

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY RemoteControlClient.FLAG_KEY_MEDIA_PLAY的同义词

int FLAG_KEY_MEDIA_PLAY_PAUSE

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY_PAUSE RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE的同义词

int FLAG_KEY_MEDIA_PREVIOUS

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PREVIOUS RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS的同义词

int FLAG_KEY_MEDIA_REWIND

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_REWIND RemoteControlClient.FLAG_KEY_MEDIA_REWIND的同义词

int FLAG_KEY_MEDIA_STOP

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_STOP RemoteControlClient.FLAG_KEY_MEDIA_STOP的同义词

int KEYCODE_MEDIA_PAUSE

同义词为 KeyEvent.KEYCODE_MEDIA_PAUSE

int KEYCODE_MEDIA_PLAY

同义词为 KeyEvent.KEYCODE_MEDIA_PLAY

int KEYCODE_MEDIA_RECORD

同义词为 KeyEvent.KEYCODE_MEDIA_RECORD

Public constructors

TransportMediator(Activity activity, TransportPerformer callbacks)
TransportMediator(View view, TransportPerformer callbacks)

Public methods

void destroy()

可选择在不再使用TransportController时调用。

boolean dispatchKeyEvent(KeyEvent event)

必须从 Activity.dispatchKeyEvent拨打电话才能让交通工具有机会拦截媒体密钥。

int getBufferPercentage()

以百分比(0-100)检索媒体流已缓冲到本地设备的金额。

long getCurrentPosition()

以毫秒为单位检索媒体流中的当前播放位置。

long getDuration()

检索媒体流的总持续时间,以毫秒为单位。

Object getRemoteControlClient()

返回与此运输相关的 RemoteControlClient

int getTransportControlFlags()

检索此传输支持的媒体传输控制按钮的标志。

boolean isPlaying()

返回玩家是否正在播放其流。

void pausePlaying()

将控制器移至暂停状态。

void refreshState()
void registerStateListener(TransportStateListener listener)

开始监听播放状态的变化。

void seekTo(long pos)

移动到媒体流中的新位置。

void startPlaying()

将控制器移到播放状态。

void stopPlaying()

将控制器移至停止状态。

void unregisterStateListener(TransportStateListener listener)

停止收听播放状态的变化。

Inherited methods

From class android.support.v4.media.TransportController
From class java.lang.Object

Constants

FLAG_KEY_MEDIA_FAST_FORWARD

int FLAG_KEY_MEDIA_FAST_FORWARD

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_FAST_FORWARD RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD的同义词

常量值:64(0x00000040)

FLAG_KEY_MEDIA_NEXT

int FLAG_KEY_MEDIA_NEXT

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_NEXT RemoteControlClient.FLAG_KEY_MEDIA_NEXT的同义词

常量值:128(0x00000080)

FLAG_KEY_MEDIA_PAUSE

int FLAG_KEY_MEDIA_PAUSE

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PAUSE RemoteControlClient.FLAG_KEY_MEDIA_PAUSE的同义词

常量值:16(0x00000010)

FLAG_KEY_MEDIA_PLAY

int FLAG_KEY_MEDIA_PLAY

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY RemoteControlClient.FLAG_KEY_MEDIA_PLAY的同义词

常量值:4(0x00000004)

FLAG_KEY_MEDIA_PLAY_PAUSE

int FLAG_KEY_MEDIA_PLAY_PAUSE

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY_PAUSE RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE的同义词

常量值:8(0x00000008)

FLAG_KEY_MEDIA_PREVIOUS

int FLAG_KEY_MEDIA_PREVIOUS

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PREVIOUS RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS的同义词

常数值:1(0x00000001)

FLAG_KEY_MEDIA_REWIND

int FLAG_KEY_MEDIA_REWIND

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_REWIND RemoteControlClient.FLAG_KEY_MEDIA_REWIND的同义词

常量值:2(0x00000002)

FLAG_KEY_MEDIA_STOP

int FLAG_KEY_MEDIA_STOP

{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_STOP RemoteControlClient.FLAG_KEY_MEDIA_STOP的同义词

常量值:32(0x00000020)

KEYCODE_MEDIA_PAUSE

int KEYCODE_MEDIA_PAUSE

同义词为 KeyEvent.KEYCODE_MEDIA_PAUSE

常量值:127(0x0000007f)

KEYCODE_MEDIA_PLAY

int KEYCODE_MEDIA_PLAY

KeyEvent.KEYCODE_MEDIA_PLAY同义词

常量值:126(0x0000007e)

KEYCODE_MEDIA_RECORD

int KEYCODE_MEDIA_RECORD

同义词为 KeyEvent.KEYCODE_MEDIA_RECORD

常量值:130(0x00000082)

Public constructors

TransportMediator

TransportMediator (Activity activity, 
                TransportPerformer callbacks)

Parameters
activity Activity
callbacks TransportPerformer

TransportMediator

TransportMediator (View view, 
                TransportPerformer callbacks)

Parameters
view View
callbacks TransportPerformer

Public methods

destroy

void destroy ()

可选择在不再使用TransportController时调用。 当您的活动/视图从窗口中分离出来时,它的资源也会自动清除,所以您通常不需要明确地调用它。

dispatchKeyEvent

boolean dispatchKeyEvent (KeyEvent event)

必须致电Activity.dispatchKeyEvent为交通工具提供拦截媒体密钥的机会。 任何此类密钥将显示在TransportPerformer

Returns
boolean

getBufferPercentage

int getBufferPercentage ()

以百分比(0-100)检索媒体流已缓冲到本地设备的金额。 如果流始终是本地的,则返回100。

Returns
int

getCurrentPosition

long getCurrentPosition ()

以毫秒为单位检索媒体流中的当前播放位置。

Returns
long

getDuration

long getDuration ()

检索媒体流的总持续时间,以毫秒为单位。

Returns
long

getRemoteControlClient

Object getRemoteControlClient ()

返回与此运输相关的RemoteControlClient 这会返回一个通用对象,因为在ICE_CREAM_SANDWICH之前RemoteControlClient不可ICE_CREAM_SANDWICH 此外,该类不会在其实现中使用RemoteControlClient,直到JELLY_BEAN_MR2 您应该始终在此处检查null,如果没有给出RemoteControlClient,则不执行任何操作; 这样您就不必担心当前的平台API版本。

请注意,这个类别拥有RemoteControlClient.OnGetPlaybackPositionListenerRemoteControlClient.OnPlaybackPositionUpdateListener回调; 你将分别通过TransportPerformer.onGetCurrentPositionTransportPerformer.onSeekTo与这些进行交互。

Returns
Object

getTransportControlFlags

int getTransportControlFlags ()

检索此传输支持的媒体传输控制按钮的标志。 结果是下列标志的组合: FLAG_KEY_MEDIA_PREVIOUSFLAG_KEY_MEDIA_REWINDFLAG_KEY_MEDIA_PLAYFLAG_KEY_MEDIA_PLAY_PAUSEFLAG_KEY_MEDIA_PAUSEFLAG_KEY_MEDIA_STOPFLAG_KEY_MEDIA_FAST_FORWARDFLAG_KEY_MEDIA_NEXT

Returns
int

isPlaying

boolean isPlaying ()

返回玩家是否正在播放其流。

Returns
boolean

pausePlaying

void pausePlaying ()

将控制器移至暂停状态。 这会更新远程控制客户端以指示它已暂停,但保持音频焦点。

refreshState

void refreshState ()

registerStateListener

void registerStateListener (TransportStateListener listener)

开始监听播放状态的变化。

Parameters
listener TransportStateListener

seekTo

void seekTo (long pos)

移动到媒体流中的新位置。

Parameters
pos long: Position to move to, in milliseconds.

startPlaying

void startPlaying ()

将控制器移到播放状态。 这会更新远程控制客户端以指示它正在播放,并为应用程序占用音频焦点。

stopPlaying

void stopPlaying ()

将控制器移至停止状态。 这会更新远程控制客户端以指示它已停止,并从应用程序中删除音频焦点。

unregisterStateListener

void unregisterStateListener (TransportStateListener listener)

停止收听播放状态的变化。

Parameters
listener TransportStateListener

Hooray!