編輯:關於Android編程
播放視頻的功能放在一個單獨的Activity當中。我們將為它們設置橫豎屏兩種布局。
在豎屏的時候,上半部分播放視頻,下半部分顯示視頻信息;
在設備旋轉成橫屏的時候,視頻進行全屏播放;
當點擊視頻列表的視頻項時,就啟動播放器播放對應的視頻。這裡我們要創建一個名字叫做VideoPlayer
的Activity,用它來完成視頻播放的任務。
另外,還要為ListView
添加一個數據項點擊時的監聽函數,
ListView
的OnItemClickListener
接口; 把要播放視頻地址的URI放入Intent
; 通過Intent,啟動視頻播放器的Activity-VideoPlayer;
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
VideoItem item = mVideoList.get(position);
Intent i = new Intent(this, VideoPlayer.class);
i.setData(Uri.parse(item.path));
startActivity(i);
}
這裡使用的Intent
是安卓系統當中連接各個組件之間的橋梁,它可以,
播放視頻可以使用Android SDK提供的現成的控件VideoView
。它是對media player
和surface
的封裝,對於初次進行視頻播放開發的我們,使用VideoView
是最簡單和方便的,不用關注太多細節上的實現方式。
VideoView
的使用,非常簡單,
在布局文件中放置一個VideoView
控件,
在Activity當中,獲取布局文件中的VideoView
,讓後設置要播放的視頻地址,
mVideoView = (VideoView) findViewById(R.id.video_view);
mVideoView.setVideoPath(path);
使用VideoView
提供的接口,控制視頻播放的流程,
//從頭開始播放視頻
mVideoView.start();
//暫停播放視頻
mVideoView.pause();
//繼續播放視頻
mVideoView.resume()
//跳轉到xxx毫秒處開始播放
mVideoView.seekTo(xxx);
還可以為VideoView
添加控制面板-MediaController
,這個面板集成了播放進度拖動、暫停、繼續播放等功能,還可以自動隱藏或顯示。如果VideoView
有父布局,那麼為它添加的MediaController
是附著在父布局的底部的。因此為了界面美觀,我們在布局文件中,將VideoView
單獨放到一個FrameLayout
當中。
這裡我們使用Android SDK自帶的Media Controller
,
MediaController controller= new MediaController(context);
mVideoView.setMediaController(controller);
我們將豎屏的布局設計成上下兩個部分,上面用VideoView
播放視頻,下面用一個TableLayout
展示視頻信息,
<framelayout android:background="@color/video_background_color" android:layout_height="0dp" android:layout_margin="10dp" android:layout_weight="1" android:layout_width="match_parent">
</framelayout>
這裡把VideoView
當到了FrameLayout
當中,讓播放的內容居中顯示,並為這個區域設置了背景顏色。
通過啟動VideoPlayer
的Intent
,獲取視頻播放的地址,
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri uri = getIntent().getData();
String path = uri.getPath();
......
}
通過播放地址,查詢該視頻相關的其他信息-視頻標題、視頻文件大小、視頻尺寸、視頻創建時間,
@Override?protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
Uri path = uri.getPath();
String[] searchKey = new String[] {
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.WIDTH,
MediaStore.Video.Media.HEIGHT,
MediaStore.Images.Media.SIZE,
MediaStore.Images.Media.DATE_ADDED
};
String where = MediaStore.Video.Media.DATA + " = '" + path + "'";
String[] keywords = null;
String sortOrder = MediaStore.Video.Media.DEFAULT_SORT_ORDER;
Cursor cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, searchKey, where, keywords, sortOrder);
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToNext();
String createdTime = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED));
String name = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE));
int size = cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.SIZE));
int width = cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.WIDTH));
int height = cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.HEIGHT));
VideoItem item = new VideoItem(path, name, createdTime);
TextView title = (TextView) findViewById(R.id.video_title);
title.setText(item.name);
TextView created = (TextView) findViewById(R.id.video_create_time);
created.setText(item.createdTime);
TextView screen = (TextView) findViewById(R.id.video_width_height);
screen.setText(width + "*" + height);
TextView fileSize = (TextView) findViewById(R.id.video_size);
fileSize.setText(String.valueOf(size / 1024 / 1024) + "M");
} else {
TextView title = (TextView) findViewById(R.id.video_title);
title.setText(R.string.unknown);
TextView created = (TextView) findViewById(R.id.video_create_time);
created.setText(R.string.unknown);
TextView screen = (TextView) findViewById(R.id.video_width_height);
screen.setText(R.string.unknown);
TextView fileSize = (TextView) findViewById(R.id.video_size);
fileSize.setText(R.string.unknown);
}
cursor.close();
}
......
}
獲取VideoView
控件,並為VideoView
設置播放的視頻。為播放界面添加了Android SDK自帶的控制面板-MediaController
,
@Override?protected void onCreate(Bundle savedInstanceState) {?
super.onCreate(savedInstanceState);
......
String path = uri.getPath();
mVideoView = (VideoView) findViewById(R.id.video_view);
mVideoView.setVideoPath(path);
MediaController controller = new MediaController(this);
mVideoView.setMediaController(controller);
}
有的時候,用戶需要暫停播放的視頻,可以通過控制面板上的按鈕操作;但有的時候,正在播放的視頻會被系統打斷,例如來了一個電話,電話Activity優先級最高,會顯示出來,讓視頻播放器暫停播放;或者用戶在播放的時候,按下了Home
鍵,切換到了主屏幕,也需要暫停播放視頻。當這些操作結束以後,再次把VideoPlayer
切換到前台的時候,我們會希望視頻繼續從剛才被打斷的地方繼續播放。
我們已經了解了Activity的生命周期,
從一個Activity創建出來,到顯示,再到用戶主動退出銷毀這個Activity,它將經歷:
onCreate()
->
onStart()
->
onResume()
->
用戶可以與Activity交互->
onPause()
->
onStop()
->
onDestroy()
;
那麼就可以選取其中的onResume()
與onPause()
,進行視頻播放暫停和繼續播放的操作。
在onPause()
中,暫停播放的視頻,記錄下當前播放的位置;在onResume()
中,從上次記錄下中斷的位置開始播放,
@Override
protected void onPause() {
super.onPause();
mVideoView.pause();
mLastPlayedTime = mVideoView.getCurrentPosition();
}
@Override
protected void onResume() {
super.onResume();
mVideoView.start();
if(mLastPlayedTime > 0) {
mVideoView.seekTo(mLastPlayedTime);
}
}
在做搜芽的過程中,發現那個外包人緣做的不行,因為啟動的時候會停頓,然後白屏一會,聯想到幾個月前我在我的三僚企業通信軟件裡面拉起9K-Mail的時候也會黑屏,所以決定學習一
一、工具干什麼都得一個好工具對吧。1.apkIDE反編譯呢,我這裡使用的是apkIDE(apk改之理),工具的話自己百度吧。個人不喜歡留一些不需要的東西在網盤裡,難得整理
SurfaceView, GLSurfaceView, SurfaceTexture和TextureView是Android當中名字比較繞,關系又比較密切的幾個類。本文基
前言最近一段時間在研究EventBus和Retrofit 的過程中,都遇到了注解這個概念。由於在學習Java的時候對這方面沒有深入了解過,所以看起相關的代碼來,總會有點不