今天繼續上一篇Android頂層窗口、浮動窗口的進階應用。上一篇主要講解了WindowManager服務和如何使用WindowManager編寫一個頂層窗口。今天主要是講講如何在頂層窗口里面播放視頻,這個功能對很多嵌入式設備來說十分有用。例如現在手機和平板上一些視頻播放器就可以實現畫中畫功能,只顯示一部分小窗口播放,用戶可以繼續操作其他功能。當你在看視頻的時候收到短信,你只要進入畫中畫功能,視頻可以繼續播放,同時你可以去操作短信功能。
(PS:新建的QQ群,有興趣可以加入一起討論:Android群:322599434)
1、MediaPlayer視頻播放
視頻播放使用Android自帶的播放功能,下面簡單介紹一下MediaPlayer的使用。MediaPlayer使用其實十分方便,不過它支持的格式並不多,不過這里主要是為了演示如何實現畫中畫功能。因為后面打算把這個畫中畫功能加入到VLC播放器里面,這樣就可以解決支持格式不多問題。
//Edited by mythou
//http://www.cnblogs.com/mythou/
// 播放界面使用surfaceview實現 surfaceView = (SurfaceView) mlayoutView.findViewById(R.id.myView); //獲取surfaceHolder,控制surfaceview surfaceHolder = surfaceView.getHolder(); //回調,檢測surfaceview的三種狀態 surfaceHolder.addCallback(this); //surfaceview的顯示源類型 surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //mediaplayer初始化 mediaPlayer = new MediaPlayer(); //設置不同的監聽接口 mediaPlayer.setOnCompletionListener(this); mediaPlayer.setOnErrorListener(this); mediaPlayer.setOnPreparedListener(this); mediaPlayer.setOnSeekCompleteListener(this); mediaPlayer.setOnVideoSizeChangedListener(this); String filePath = "/mnt/card/test.mp4";// "/mnt/sdcard/test.mp4";// // 本地地址和網絡地址都可以 try { mediaPlayer.setDataSource(filePath); } catch (IllegalArgumentException e) { // TODO: handle exception Log.v(LOGCAT, e.getMessage()); onExit(); }
上面是初始化surfaceView和MeidaPlayer的代碼,surfaceview在android應用開發里面十分重要,基本上設計視頻或者動畫類型的界面,都需要用到它。如果不了解的朋友,建議好好去熟悉一下這個類的使用。下面我們看看surfaceview的回調接口:
//Edited by mythou
//http://www.cnblogs.com/mythou/
@Override public void surfaceCreated(SurfaceHolder holder) { Log.v(LOGCAT, "suc calles"); mediaPlayer.setDisplay(holder);// 若無次句,將只有聲音而無圖像 try {
//播放視頻 mediaPlayer.prepare(); } catch (IllegalStateException e) { onExit(); } catch (IOException e) { onExit(); }
}
上面是surfaceview里面其中一個回調接口,在這里我們處理視頻准備開始播放,以及把surfaceview設置到MediaPlayer里面,讓他們兩者協調工作。播放的功能是MediaPlayer實現,而畫面顯示是依賴surfaceview實現。
2、設置WindowManager窗口
//Edited by mythou
//http://www.cnblogs.com/mythou/
public void initWindow() { // 獲取WindowManager wm = (WindowManager) context.getApplicationContext().getSystemService( "window"); // 設置LayoutParams(全局變量)相關參數 // wmParams = ((MyApplication)getApplication()).getMywmParams(); wmParams = new WindowManager.LayoutParams(); /** * 以下都是WindowManager.LayoutParams的相關屬性 具體用途可參考SDK文檔 */ wmParams.type = /*LayoutParams.TYPE_SYSTEM_ALERT | */LayoutParams.TYPE_SYSTEM_OVERLAY; // 設置window type // 設置圖片格式,效果為背景透明 wmParams.format = PixelFormat.TRANSPARENT; // 設置Window flag wmParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_LAYOUT_NO_LIMITS; /* * 下面的flags屬性的效果形同“鎖定”。 懸浮窗不可觸摸,不接受任何事件,同時不影響后面的事件響應。 * wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL | * LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE; */ wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 調整懸浮窗口至左上角 // 以屏幕左上角為原點,設置x、y初始值 currentDisplay = wm.getDefaultDisplay(); WIDTH = currentDisplay.getWidth(); HEIGHT = currentDisplay.getHeight(); wmParams.x = (WIDTH - VIEW_WIDTH) / 2; wmParams.y = 0; // 設置懸浮窗口長寬數據 wmParams.width = VIEW_WIDTH; wmParams.height = VIEW_HEIGHT; }
上面是使用WindowManager設置浮動窗口流程,跟我們上一篇界面的方法一致,具體不了解的朋友,可以看看我上一篇文章。
3、界面綁定畫面
下面我們看看如何把我們的視頻播放界面綁定到頂層顯示View上面,上一篇已經介紹過,只需要調用addview方法即可。
//Edited by mythou
//http://www.cnblogs.com/mythou/
MyFloatView sFloatView; ViewGroup fView; //綁定XML配置的界面 fView = (ViewGroup) View.inflate(context, R.layout.main, null); // 顯示myFloatView圖像 sFloatView = new MyFloatView(fView); sFloatView.bindViewListener(); sFloatView.showLayoutView();
上面是通過配置一個XML來顯示界面,XML界面里面定義了Surfaceview類,最后在FloatView里面的showLayoutView調用WindowManager的addView添加到窗口服務里面。
public void showLayoutView() { wm.addView(mlayoutView, wmParams); }
上面就是大概的顯示綁定流程,具體詳細代碼,請查看Demo里面的代碼。這個Demo是在CSDN上面下載的,本來是想自己寫一個,不過既然有開發者已經分享出來,我就沒有重新自己寫了,這個Demo我修改了一些錯誤,原版下載的,導入后會關聯一個工程導致出錯,修正了這個問題。下載我下面的代碼,直接導入就可以使用。然后設置一下視頻路徑。
這只是一個很簡單功能,視頻路徑也是寫死了,只是讓大家知道如何實現畫中畫功能。可以把這功能移植到我們的多媒體播放器上面實現視頻的畫中畫播放。
測試Demo:MoviewView2013-8-10.rar
相關文章:
Android 實現頂層窗口、浮動窗口(附Demo)
Edited by mythou
原創博文,轉載請標明出處:http://www.cnblogs.com/mythou/p/3250302.html