前面我们把Gallery3D的消息流程 刷新流程 数据流程 界面切换流程全部理清楚了,是不是很有成就感觉。
如果弄懂了,添加两个按钮的作业应该没有什么问题,甚至添加一个新的层都不会有问题。
我们讲了这么久其实才讲了一个Activity,其实还有一个比较重要的Activity.我们去看下配置文件AndroidManifast.xml
<activity android:name="com.cooliris.media.MovieView"
android:label="@string/movie_view_label"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="rtsp" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="video/*" />
<data android:mimeType="application/sdp" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:mimeType="video/mpeg4" />
<data android:mimeType="video/mp4" />
<data android:mimeType="video/3gp" />
<data android:mimeType="video/3gpp" />
<data android:mimeType="video/3gpp2" />
</intent-filter>
</activity>
我们可以看到这个Activity是没有标题的一个全屏幕的Activity, 在播放流媒体是和特定类型的视频时会走我们这个Actitity.
这个内容不多,我全部弄过来看下。
public class MovieView extends Activity {
@SuppressWarnings("unused")
private static final String TAG = "MovieView";
private App mApp = null;
private MovieViewControl mControl;
private boolean mFinishOnCompletion;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mApp = new App(MovieView.this);
setContentView(Res.layout.movie_view);
View rootView = findViewById(Res.id.root);
Intent intent = getIntent();
mControl = new MovieViewControl(rootView, this, intent.getData()) {
@Override
public void onCompletion() {
if (mFinishOnCompletion) {
finish();
}
}
};
if (intent.hasExtra(MediaStore.EXTRA_SCREEN_ORIENTATION)) {
int orientation = intent.getIntExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
if (orientation != getRequestedOrientation()) {
setRequestedOrientation(orientation);
}
}
mFinishOnCompletion = intent.getBooleanExtra(MediaStore.EXTRA_FINISH_ON_COMPLETION, true);
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
winParams.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;
win.setAttributes(winParams);
}
@Override
public void onPause() {
mControl.onPause();
super.onPause();
mApp.onPause();
}
@Override
public void onResume() {
mControl.onResume();
super.onResume();
mApp.onResume();
}
@Override
public void onDestroy() {
mControl.onDestroy();
mApp.shutdown();
super.onDestroy();
}
}
先看下面简单的,就是mControl和mApp两个成员变量在跟随动作,super咱就不管了。
App我们看过代码也非常简单,就是纪录一个是否暂停的变量,让别的地方好检测而已。
然后就剩下一个控件 MovieViewControl类型的mControl
然后我们看下他加载的layout 文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
<LinearLayout android:id="@+id/progress_indicator"
android:orientation="vertical"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar android:id="@android:id/progress"
style="?android:attr/progressBarStyleLarge"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView android:paddingTop="5dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/loading_video" android:textSize="14sp"
android:textColor="#ffffffff" />
</LinearLayout>
</RelativeLayout>
LinerLayout里面都是显示的进度拳和进度的显示字符串,我们再去OnCreate里面看下,一开始就是设置的Movie_View,显示的就是加载视频的界面,然后将接受到的Intent传到控件中去,
public MovieViewControl(View rootView, Context context, Uri videoUri) {
mContentResolver = context.getContentResolver();
mVideoView = (VideoView) rootView.findViewById(Res.id.surface_view);
mProgressView = rootView.findViewById(Res.id.progress_indicator);
mUri = videoUri;
// For streams that we expect to be slow to start up, show a
// progress spinner until playback starts.
String scheme = mUri.getScheme();
if ("http".equalsIgnoreCase(scheme) || "rtsp".equalsIgnoreCase(scheme)) {
mHandler.postDelayed(mPlayingChecker, 250);
} else {
mProgressView.setVisibility(View.GONE);
}
我们就会发现,如果不是流媒体,进度条就直接隐藏了,那么进度条基本就是一闪而过
如果是流媒体,就会延迟.25秒,并且
Runnable mPlayingChecker = new Runnable() {
public void run() {
if (mVideoView.isPlaying()) {
mProgressView.setVisibility(View.GONE);
} else {
mHandler.postDelayed(mPlayingChecker, 250);
}
}
};
这里就会发现,如果是流媒体,没有开始播放,就会一直有进度条在提示。
接下去的代码
mVideoView.setOnErrorListener(this);
mVideoView.setOnCompletionListener(this);
mVideoView.setVideoURI(mUri);
mVideoView.setMediaController(new MediaController(context));
// make the video view handle keys for seeking and pausing
mVideoView.requestFocus();
设置错误处理,设置完成的监听,设置要播放的视频地址,设置播放器的播放控件,设置焦点
Intent i = new Intent(SERVICECMD);
i.putExtra(CMDNAME, CMDPAUSE);
context.sendBroadcast(i);
播放之前将Music 给暂停。
最后播放
mVideoView.start();
暂停的时候有个进度条控件,就是MediaControler控件,这个控件是Framework里面写好的,还有播放代码也是系统写好的
import android.widget.MediaController;
import android.widget.VideoView;
private final VideoView mVideoView;
其实,这个播放器只是一个空空的框架,什么都是调用系统的内容。请看如下代码
public void onPause() {
mHandler.removeCallbacksAndMessages(null);
setBookmark(mVideoView.getCurrentPosition(), mVideoView.getDuration());
mVideoView.suspend();
}
public void onResume() {
mVideoView.resume();
}
public void onDestroy() {
mVideoView.stopPlayback();
}
public boolean onError(MediaPlayer player, int arg1, int arg2) {
mHandler.removeCallbacksAndMessages(null);
mProgressView.setVisibility(View.GONE);
return false;
}
基本的2.3的Gallery3D的内容基本上就是这些了,下次我将研究Android 4.2的Gallery的代码,让我们看看都有什么改变?