Android系統編程入門系列之硬體交互——多媒體展示

前兩篇文章通過麥克風硬體和攝影機硬體分別採集音頻和影片的多媒體數據,在得到的多媒體數據通常是以編碼文件的格式存儲,在用戶需要展示時,可通過設備的內置擴音器或藍牙耳機等硬體播放音頻,通過設備的顯示器或外接投影儀等硬體播放照片、動畫或影片。

可以將這些展示類設備分為兩類。
一類是內置類多媒體硬體,是通過線路硬連接到設備CPU控制中心,所以在應用程式中可直接調取系統提供的相關介面直接使用這類設備。比如移動手機的內置擴音器、聽筒、有線耳機、螢幕等硬體。
另一類是外接類多媒體硬體,是通過配合下文即將介紹的藍牙或網路等通訊類硬體,通過無線軟連接到設備CPU控制中心,在使用這類設備前,必須先配合通訊類硬體的使用。比如藍牙耳機、投影儀等硬體。
本篇只介紹在內置類多媒體硬體上的使用流程。

播放音頻

對於音頻的播放,主要藉助內置擴音器,使用系統提供的android.media.MediaPlayer類。

使用其無參構造方法後,調用該對象的setDataSource(String path)等系列方法,設置要播放的音頻源。該系列方法有多個重寫,除了上邊參數 path 所表示的本地文件格式的音頻源,還可以設置遠程網路 Uri 格式的音頻源。

除此之外,還需要設置播放的音頻流類型,不過設置方法在不同版本上有所區別。
在Android5.0即API級別21之前,調用setAudioStreamType(int streamtype)方法,參數 streamtype 是由android.media.AudioManager音頻管理類定義的常量,其值包括標記為語音通話音頻流的AudioManager.STREAM_VOICE_CALL=0,標記為系統音頻流的AudioManager.STREAM_SYSTEM=1,語音鈴聲的AudioManager.STREAM_RING=2,或者多媒體音樂流的AudioManager.STREAM_MUSIC=3等多種音頻流類型。
從Android5.0即API級別21開始,改用setAudioAttributes(AudioAttributes attributes)方法,參數 attributes 是android.media.AudioAttributes音頻屬性類構造的對象,而AudioAttributes對象則是通過android.media.AudioAttributes.Builder建造者模式構造的。在無參構造建造者AudioAttributes.Builder對象後,調用setUsage(int usage)方法設置音頻屬性的使用者,調用setContentType(int contentType)方法設置音頻流內容類型,上述方法中的參數 usage 和參數 contentType 都是AudioAttributes定義的常量值。之後通過build()方法返回AudioAttributes音頻屬性類的實例化對象。

在音頻相關參數設置之後,就可以準備音頻以通過系統獲取相關硬體設備了。
在載入本地的小文件時,可以直接調用 prepare() 方法,程式碼執行到此處時會停止後續程式碼運行,直到獲取到相關資源,才會繼續執行音頻準備完成之後的相關操作。因此在系統主執行緒中調用該方法時需要注意ANR異常。
通常在載入網路資源或過大的文件時,調用prepareAsync()方法,該方法會非同步獲取相關資源,後續程式碼繼續執行,而當應用程式獲取到相關資源後,將回調setOnPreparedListener(MediaPlayer.OnPreparedListener listener)中傳入的 listener 參數對象的onPrepared(MediaPlayer mp)方法,而這裡的參數 mp 也就是上文調用prepareAsync()的MediaPlayer對象。因此在實現android.media.MediaPlayer.OnPreparedListener介面的onPrepared(MediaPlayer mp)方法中,可以繼續執行音頻準備完成之後的相關操作。

在音頻準備完成之後,便可以在合適的時機執行音頻的播放流程了。
調用start()方法即可開始播放;
在音頻播放過程中,同樣可以調用pause()方法暫停播放;
調用seekTo(long msec, int mode)方法可以將播放位置移動到參數 msec 指定的毫秒級同步時刻,參數 mode 是MediaPlayer中的常量值,包括實際定位到參數 msec 指定的同步位置之前的MediaPlayer.SEEK_PREVIOUS_SYNC=0,實際定位到參數 msec 指定的同步位置之後的MediaPlayer.SEEK_NEXT_SYNC=1,實際定位到參數 msec 指定的同步位置最近的MediaPlayer.SEEK_CLOSEST_SYNC=2等幾種可選模式;
調用stop()方法停止播放,將會釋放應用程式所獲取的包括硬體的相關資源。

顯示圖片或影片

對於靜態圖片的展示,通常使用android.widget.ImageView類似控制項,直接載入靜態圖片。

對於無聲的動態圖展示,通常使用android.view.SurfaceView控制項,在該控制項上可以繪製幾乎任何你能想到的效果。

對於自帶音頻的有聲動圖(即影片)展示,可以使用上述方案的結合,也可使用系統提供的android.widget.VideoView控制項,可以更方便的載入影片並展示。

同時,由於圖片或影片展示都只是藉助螢幕繪製,所以使用介面繪製展示一文中的相關知識內容即可實現。而且其他開發者和團隊也開發了一系列的相關庫以供使用,這在學習過程中並不算難點,故不再贅述。