Android系統編程入門系列之硬件交互——多媒體麥克風

多媒體攝像頭及相關硬件文章中,對攝像頭的使用方式需要區分應用程序的目標版本以使用不同的代碼流程,而與之相比,麥克風硬件的使用就簡單多了。

麥克風及相關硬件

麥克風硬件在移動設備上作為音頻的採集設備,由於只需要一個收聲口,其顏值對用戶來說關注度比較低。而且不同的麥克風硬件在性能上差距不大,其應用場景也只是在錄製視頻時的音頻採集,或單獨的音頻採集,故使用流程和相關操作都比較簡單易懂。

只是在目標版本為Android9.0即API 28即以上的系統中,如果應用程序想使用麥克風,必須保持前台運行,或使用前台服務以訪問麥克風並採集音頻。否則如果應用程序切換到後台,將無法正常使用麥克風采集的數據。

權限聲明

首先對麥克風硬件的使用權限進行聲明,其權限名及值為Manifest.permission.RECORD_AUDIO=”android.permission.RECORD_AUDIO”。該權限必須在應用程序的清單文件中聲明,並且在目標版本為Android6.0即API 23及以上的系統中還需要動態申請該權限,經用戶授權後方可啟用麥克風。

使用流程

關於麥克風的音頻採集流程,與在API 21以下使用攝像頭的流程相似。首先檢測麥克風硬件,在能獲取到Context上下文環境對象的位置,調用上下文環境對象的getPackageManager()方法獲取android.content.pm.PackageManager包管理類的實例化對象,進而通過該對象的hasSystemFeature(String featureName)方法,使參數 featureName 值為PackageManager.FEATURE_MICROPHONE 代表麥克風功能,來判斷當前系統是否有麥克風硬件的支持。

對於支持麥克風硬件的設備,在目標版本為Android9.0即API 28及以上的系統中,可以獲取麥克風硬件的詳細信息。可以調用上下文環境對象的getSystemService(String name)方法獲取系統服務中的音頻管理類,該方法的參數 name 值為Context.AUDIO_SERVICE=\"audio\",並將返回對象強制轉換為android.media.AudioManager音頻管理類。藉助AudioManager音頻管理類對象,可以訪問音頻採集和播放相關的信息。其中,調用該對象的getMicrophones()方法,得到返回的android.media.MicrophoneInfo類型組成的列表,而這裡的MicrophoneInfo麥克風信息類對象,則對應保存了該設備上可使用的每個麥克風信息。

音頻採集

對於麥克風硬件的數據採集,主要用到android.media.MediaRecorder多媒體錄製類,該類在多媒體攝像頭及相關硬件中實現視頻錄製功能時也有使用。這裡也將詳細說明MediaRecorder多媒體錄製類的使用方式。

首先實例化多媒體錄製類對象,使用MediaRecorder(Context context)構造方法。該方法的參數 context 即當前使用多媒體錄製類的上下文環境對象。

在初始化MediaRecorder多媒體錄製類對象後,可以調用該對象的setX系列方法設置相關配置項。
在錄製音頻時,需要選擇音頻源。設置音頻源可以調用該對象的setAudioSource(int audioSource)方法,其中參數 audioSourceint類型的標誌位,其值通常設置為麥克風的音頻源MediaRecorder.AudioSource.MIC=1,另外還可以是適用於通話的麥克風MediaRecorder.AudioSource.VOICE_CALL=4,或者適用於現場直播的麥克風MediaRecorder.AudioSource.VOICE_PERFORMANCE=10等。
在錄製音頻時,麥克風采集的音頻通常需要編碼輸出,設置編碼格式可以調用該對象的setAudioEncoder(int audio_encoder)方法,其參數 audio_encoder 同樣是int類型的標誌位,其值可以是AMR NB格式的MediaRecorder.AudioEncoder.AMR_NB=1,AMR WB格式的MediaRecorder.AudioEncoder.AMR_WB=2,AAC LC格式的MediaRecorder.AudioEncoder.AAC=3,OGG格式的MediaRecorder.AudioEncoder.VORBIS=6,OPUS格式的MediaRecorder.AudioEncoder.OPUS=7等。
在錄製音頻後,可以將數據輸出到文件中,設置輸出音頻文件可以調用該對象的setOutputFile(String path)方法,其參數 path 指定了輸出文件的絕對路徑。
在輸出文件時同樣要設置輸出格式,調用該對象的setOutputFormat(int output_format)方法,其參數 output_format 同樣是int類型的標誌位,與音頻編碼格式對應,其值可以調用MediaRecorder.OutputFormat靜態類的相關常量。

MediaRecorder對象設置完相關準備工作後,可以調用該對象的prepare()方法,獲取相關硬件,準備開始採集音頻數據。
而調用MediaRecorder對象的start()方法,則開始啟動採集音頻,並將數據輸出到指定的文件中。

錄製音頻過程中,可以調用MediaRecorder對象的pause()方法暫停錄製,數據將會暫停輸出到指定文件。
如果想再次繼續錄製音頻並將數據輸出到文件,可以調用MediaRecorder對象的resume()方法繼續錄製。

最終,需要停止採集音頻,調用MediaRecorder對象的stop()方法停止錄製,數據將停止輸出到指定文件,並關閉對指定文件的使用狀態。

在停止錄製後,必須調用MediaRecorder對象的release()方法,釋放當前多媒體錄製類所佔用的資源,包括對麥克風的佔用狀態等。

使用麥克風的音頻採集功能,還可以通過android.media.AudioRecord音頻錄製類實現。而且MediaRecorder多媒體錄製類中關於音頻錄製的功能,在底層同樣是通過AudioRecorder音頻錄製類實現的,所以初級階段掌握MediaRecorder多媒體錄製類的相關使用將會更加實用。