懸浮視頻播放器實現


1.    背景:

我們都知道,Android手機的原生視頻播放器並沒有懸浮功能,也就是說當用戶看視頻時,就不能有其他方面的操作,例如看短信、看網頁等打開其他應用。如果我們的手機能讓用戶一邊看視頻,一邊對手機進行其他方面操作,對用戶來說是非常不錯的體驗,這樣能提高我們手機的競爭力!同時我們的一些客戶也有這方面的需求,因此我們有必要實現懸浮視頻播放器這功能。

2.    核心知識點歸納:

1).核心類:MediaScanner掃描類

Android系統在開機的時候,MediaScanner服務會在后台自動掃描系統內存及SD上的圖片、音頻、視頻等文件資源,將這些媒體信息加入到MediaStore數據庫中。程序可以直接從MediaStore中讀取相應的媒體信息。通過注冊監聽MediaScanner廣播的Intent,可以獲知MediaScanner服務是否在進行后台的掃描工作:

Intent.ACTION_MEDIA_SCANNER_STARTED表示MeidaScanner開始掃描;

Intent.ACTION_MEDIA_SCANNER_FINISHED表示MediaScanner掃描結束;

MediaScanner這項功能使用到的三種android的基本組件:

(1)MediaScannerService(從Service中派生),完成掃描任務,並將掃描結果放入到媒體數據庫中。

(2)MediaProvider(ContentProvider派生),針對媒體庫進行相關操作請求,一般情況就是寫,刪,查,更操作。

(3)MediaScannerReceiver接收外界的掃描請求。

 

這里我們只需要明白一點是:多媒體數據庫中的信息是由MediaScanner添加的。

 

2.核心類:MediaStore 多媒體類

MediaScanner將掃描媒體文件獲得的信息全部存儲在MediaStore數據庫中。MediaStore是基於SQLite數據庫系統的,通過ContentProvider方式,程序可以對MediaStore數據庫進行增刪查改等操作。MediaStore的數據庫文件位於/data/data/com.android.providers/databases,通常可以發現兩個數據庫文件:

internal.db:對應內部存儲空間的媒體數據庫文件;

external-xxxxxxxx.db:對應外部存儲空間的媒體數據文件。

 

這里我們看看視頻資源的數據庫內容:

public static final UrimExternalVideoStorageURI =Uri.parse("content://media/external/video/media");

相當於mExternalVideoStorageURI== MediaStore.Video.Media.EXTERNAL_CONTENT_URI

一部分數據庫里的信息(不解析了,看名字就知道什么意思!):

Video.Media._ID,

Video.Media.DATA,

Video.Media.DATE_TAKEN,

Video.Media.TITLE,

Video.Media.DISPLAY_NAME,

Video.Media.DURATION,

Video.Media.BOOKMARK,

Video.Media.MIME_TYPE,

Video.Media.SIZE,

Media.IS_DRM,

MediaColumns.DATE_MODIFIED,

 

調用利用ContentResolver去掉用那些封裝好的接口就可以進行數據庫的操作了。

 

3).視頻的播放方式:

在Android中,我們有三種方式來實現視頻的播放。

1、使用其自帶的播放器。指定Action為ACTION_VIEW,Data為Uri,Type為其MIME類型。

2、使用VideoView來播放。在布局文件中使用VideoView結合MediaController來實現對其控制。

3、使用MediaPlayer類和SurfaceView來實現。這種方式最靈活,也最復雜。

 

我們這里使用第二種方法來實現我們的功能!

 

先看看通過VideoView播放視頻的步驟:

 1、在界面布局文件中定義VideoView組件,或在程序中創建VideoView組件

 2、調用VideoView的如下兩個方法來加載指定的視頻

        setVidePath(String path):加載path文件代表的視頻

        setVideoURI(Uri uri):加載uri所對應的視頻

3、調用VideoView的start()、stop()、psuse()方法來控制視頻的播放

VideoView通過與MediaController類結合使用,開發者可以不用自己控制播放與暫停

 

 

4).懸浮框的實現

 

整個Android的窗口機制是基於一個叫做 WindowManager,這個接口可以添加view到屏幕,也可以從屏幕刪除view。它面向的對象一端是屏幕,另一端就是View,直接忽略我們以前的Activity或者Dialog之類的東東。其實我們的Activity或者Diolog底層的實現也是通過WindowManager,這個 WindowManager是全局的,整個系統就是這個唯一的東東。它是顯示View的最底層了。

   WindowManager主要用來管理窗口的一些狀態、屬性、view增加、刪除、更新、窗口順序、消息收集和處理等。通過Context.getSystemService(Context.WINDOW_SERVICE)的方式可以獲得WindowManager的實例.WindowManager繼承自ViewManager,里面涉及到窗口管理的三個重要方法,分別是:

     * addView();

     *updateViewLayout();

     *removeView(); 

 

現在我們看看視頻懸浮框的屬性代碼:

寫了一個懸浮類FloatWidget,里面的設置屬性函數如下


顯示函數:

 

3.實現流程:

我這里直接在Gallery2應用里添加這個懸浮框播放功能,跟Gallery2合在一起,因為原生的視頻播放功能在這應用里,這樣就比較方便實現此功能。

 

實現的大概流程:

首先一個本地的視頻正在播放時(MovieActivity類),程序里用變量保存當前播放視頻的URI和MIME類型,當點擊某個按鈕時,會先把當前視頻的播放位置保存到數據庫里,然后開始進入懸浮框初始化(顯示位置、大小、屬性等),懸浮框里包含了VideoView類,這個類就是用於播放視頻,將之前保存的數據(URI等)對其賦值,然后關閉當前播放視頻的窗口,這樣浮動視頻框就出來了!同樣當懸浮視頻切換到本地原生視頻播放器時,也會保留當前播放視頻的播放位置,在重新進入MovieActivity類時,將這保留的最新數據進行對其賦值,這樣就可以繼續播放了!

 

看看會用到那些類:

 

接下來就是核心代碼方面的具體分析吧

本地播放視頻類是MovieActivity,我們在其onCreate()方法里有如下代碼:




 

以上的代碼主要是創建VideoCursorManager類對當前播放視頻的數據進行保存,以及當懸浮視頻播放器切換到原生的播放器時,把保存到視頻數據進行賦值。

為了方便我實現這功能,我在MovieActivity類里對返回鍵的觸發做了修改,當點擊返回鍵時,其就切換到懸浮視頻播放器,代碼如下:



 

接着我們看看FloatVideoView類的init()函數



floating_video_view.xml:


懸浮框里有關閉、播放、暫停、切換功能!並且對於用戶來說,懸浮框需要能拖動的觸摸功能!

實現代碼如下:

FloatVideoView 需要繼承View.OnTouchListener




先看mFloatWidget的onTouchEvent功能:



這是對拖動懸浮框時,位置改變的代碼。

接着是mFloatingViewDetector.onTouchEvent(event)

mFloatingViewDetector = new GestureDetector(mContext,floatingViewDetectorlistener);



這樣就可實現對懸浮框的那些功能操作了!

現在我們看看如何從懸浮框切換到原生視頻播放器里的。

主要代碼如下:


這樣就開始跑到MovieActivity類里,上面代碼在其onCreate()已做相關處理了。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com