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); } }
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 |
int |
KEYCODE_MEDIA_PLAY |
int |
KEYCODE_MEDIA_RECORD |
Public constructors |
|
---|---|
TransportMediator(Activity activity, TransportPerformer callbacks) |
|
TransportMediator(View view, TransportPerformer callbacks) |
Public methods |
|
---|---|
void |
destroy() 可选择在不再使用TransportController时调用。 |
boolean |
dispatchKeyEvent(KeyEvent event) 必须从 |
int |
getBufferPercentage() 以百分比(0-100)检索媒体流已缓冲到本地设备的金额。 |
long |
getCurrentPosition() 以毫秒为单位检索媒体流中的当前播放位置。 |
long |
getDuration() 检索媒体流的总持续时间,以毫秒为单位。 |
Object |
getRemoteControlClient() 返回与此运输相关的 |
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
|
int FLAG_KEY_MEDIA_FAST_FORWARD
{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_FAST_FORWARD RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD的同义词
常量值:64(0x00000040)
int FLAG_KEY_MEDIA_NEXT
{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_NEXT RemoteControlClient.FLAG_KEY_MEDIA_NEXT的同义词
常量值:128(0x00000080)
int FLAG_KEY_MEDIA_PAUSE
{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PAUSE RemoteControlClient.FLAG_KEY_MEDIA_PAUSE的同义词
常量值:16(0x00000010)
int FLAG_KEY_MEDIA_PLAY
{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY RemoteControlClient.FLAG_KEY_MEDIA_PLAY的同义词
常量值:4(0x00000004)
int FLAG_KEY_MEDIA_PLAY_PAUSE
{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY_PAUSE RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE的同义词
常量值:8(0x00000008)
int FLAG_KEY_MEDIA_PREVIOUS
{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PREVIOUS RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS的同义词
常数值:1(0x00000001)
int FLAG_KEY_MEDIA_REWIND
{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_REWIND RemoteControlClient.FLAG_KEY_MEDIA_REWIND的同义词
常量值:2(0x00000002)
int FLAG_KEY_MEDIA_STOP
{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_STOP RemoteControlClient.FLAG_KEY_MEDIA_STOP的同义词
常量值:32(0x00000020)
int KEYCODE_MEDIA_RECORD
同义词为 KeyEvent.KEYCODE_MEDIA_RECORD
常量值:130(0x00000082)
TransportMediator (Activity activity, TransportPerformer callbacks)
Parameters | |
---|---|
activity |
Activity
|
callbacks |
TransportPerformer
|
TransportMediator (View view, TransportPerformer callbacks)
Parameters | |
---|---|
view |
View
|
callbacks |
TransportPerformer
|
void destroy ()
可选择在不再使用TransportController时调用。 当您的活动/视图从窗口中分离出来时,它的资源也会自动清除,所以您通常不需要明确地调用它。
boolean dispatchKeyEvent (KeyEvent event)
必须致电Activity.dispatchKeyEvent
为交通工具提供拦截媒体密钥的机会。 任何此类密钥将显示在TransportPerformer
。
Returns | |
---|---|
boolean |
int getBufferPercentage ()
以百分比(0-100)检索媒体流已缓冲到本地设备的金额。 如果流始终是本地的,则返回100。
Returns | |
---|---|
int |
long getCurrentPosition ()
以毫秒为单位检索媒体流中的当前播放位置。
Returns | |
---|---|
long |
long getDuration ()
检索媒体流的总持续时间,以毫秒为单位。
Returns | |
---|---|
long |
Object getRemoteControlClient ()
返回与此运输相关的RemoteControlClient
。 这会返回一个通用对象,因为在ICE_CREAM_SANDWICH
之前RemoteControlClient不可ICE_CREAM_SANDWICH
。 此外,该类不会在其实现中使用RemoteControlClient,直到JELLY_BEAN_MR2
。 您应该始终在此处检查null,如果没有给出RemoteControlClient,则不执行任何操作; 这样您就不必担心当前的平台API版本。
请注意,这个类别拥有RemoteControlClient.OnGetPlaybackPositionListener
和RemoteControlClient.OnPlaybackPositionUpdateListener
回调; 你将分别通过TransportPerformer.onGetCurrentPosition
和TransportPerformer.onSeekTo
与这些进行交互。
Returns | |
---|---|
Object |
int getTransportControlFlags ()
检索此传输支持的媒体传输控制按钮的标志。 结果是下列标志的组合: FLAG_KEY_MEDIA_PREVIOUS
, FLAG_KEY_MEDIA_REWIND
, FLAG_KEY_MEDIA_PLAY
, FLAG_KEY_MEDIA_PLAY_PAUSE
, FLAG_KEY_MEDIA_PAUSE
, FLAG_KEY_MEDIA_STOP
, FLAG_KEY_MEDIA_FAST_FORWARD
, FLAG_KEY_MEDIA_NEXT
Returns | |
---|---|
int |
boolean isPlaying ()
返回玩家是否正在播放其流。
Returns | |
---|---|
boolean |
void pausePlaying ()
将控制器移至暂停状态。 这会更新远程控制客户端以指示它已暂停,但保持音频焦点。
void refreshState ()
void registerStateListener (TransportStateListener listener)
开始监听播放状态的变化。
Parameters | |
---|---|
listener |
TransportStateListener
|
void seekTo (long pos)
移动到媒体流中的新位置。
Parameters | |
---|---|
pos |
long : Position to move to, in milliseconds. |
void startPlaying ()
将控制器移到播放状态。 这会更新远程控制客户端以指示它正在播放,并为应用程序占用音频焦点。
void stopPlaying ()
将控制器移至停止状态。 这会更新远程控制客户端以指示它已停止,并从应用程序中删除音频焦点。
void unregisterStateListener (TransportStateListener listener)
停止收听播放状态的变化。
Parameters | |
---|---|
listener |
TransportStateListener
|