1. 程式人生 > >Android開發--WebView簡單錄音功能的實現

Android開發--WebView簡單錄音功能的實現

由於專案需要在一個使用了WebView控制元件的網頁上實現本地錄音的功能,以下為部分步驟:

1.在MainActivity類中新增如下成員變數:

private MediaRecorder recorder;  // 錄音類
private String fileName;  // 錄音生成的檔案儲存路徑

2.新增許可權

①在AndroidManifest.xml檔案中新增如下許可權:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
②在onCreate函式中檢查這些許可權(該操作僅針對安卓6.0及以上的使用者,低版本使用者可能不需要這一步)

onCreate函式中請求許可權

requestPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
requestPermission(Manifest.permission.RECORD_AUDIO);
requestPermission函式如下:
private void requestPermission(String permission){
    if(ContextCompat.checkSelfPermission(this, permission)!= PackageManager.PERMISSION_GRANTED){
        ActivityCompat.requestPermissions(this, new String[]{permission}, 0);
    }
}

3.onCreate函式中初始化錄音檔案儲存路徑

fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/audiorecordertest.amr";
4.開始錄音函式,建立錄音物件並進行設定
public boolean startRecord() {
    recorder = new MediaRecorder();
    try {
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    }catch (IllegalStateException e){
        Log.i(LOG_TAG, "設定錄音源失敗");
        e.printStackTrace();
    }

    recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
    recorder.setOutputFile(fileName);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    try {
        recorder.prepare();
    }catch (IOException e){
        Log.e(LOG_TAG, "準備失敗");
        e.printStackTrace();
    }
    recorder.start();
    Log.i(LOG_TAG, "開始錄音...");
    return true;
}
5.停止錄音函式
public void stopRecord() {
    recorder.stop();
    recorder.reset();
    recorder.release();
    recorder = null;
    Log.i(LOG_TAG, "停止錄音");
}

6.以上安卓的本地Java程式碼,在網頁端需要呼叫這些方法來實現本地錄音功能

7.當完成錄音後,錄音內容會儲存在fileName變數對應的本地檔案中,此時需要將該檔案取出到前端web頁面中,然後完成檔案上傳

首先需要在web頁面中嵌入一個隱藏的表單來獲取檔案:

<form id="submit-file" style="display: hidden;" action="upload_file.php" method="post"	enctype="multipart/form-data">
	<input id="ttt" type="file" name="file" accept="audio/amr" /> 
</form>

然後模擬一次檔案選擇和表單提交操作,將檔案獲取到前臺來,並上傳檔案內容。

引入相關js檔案:

<script src="jquery-3.2.1.js"></script>
<script src="jquery-form.js"></script>

模擬選擇檔案並上傳:
// 獲取錄音檔案並上傳
$("#ttt").trigger("click");
window.setTimeout(function(){
$("#submit-file").ajaxSubmit(function(message) { 
$("body").append("<p>"+message+"</p>");
	});
}, 3000);
其中延時三秒是為了確保檔案已經由後臺傳輸至前臺頁面,同時ajax提交會只提交表單而不會發生跳轉。其中模擬點選事件會觸發webview本地的onFileChooser函式,具體如下:
webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        result.confirm(JSBridge.callJsPrompt(MainActivity.this, webView, message));
        return true;
    }

    @Override
    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
        File f = new File(fileName);
        if(f.exists()){
            Uri u = Uri.fromFile(f);
            filePathCallback.onReceiveValue(new Uri[]{u});
        }
        return true;
    }
});
8.伺服器端需要對上傳的檔案接收並進行轉碼,由於錄音生成到的是amr檔案,通過ffmpeg可以轉碼成mp3檔案。伺服器端php程式碼如下:
<?php
if ($_FILES ["file"] ["error"] > 0) {
	echo "Return Code: " . $_FILES ["file"] ["error"] . "<br />";
} else {
	if (file_exists ( "upload/" . $_FILES ["file"] ["name"] )) {
		echo $_FILES ["file"] ["name"] . " already exists. ";
	} else {
		move_uploaded_file ( $_FILES ["file"] ["tmp_name"], "upload/" . $_FILES ["file"] ["name"] );
		// TODO 檔案轉碼,此處需要重新設計生成的檔案的名稱
 		exec("upload\\ffmpeg.exe -i upload\\audiorecordertest.amr "."upload\\1.mp3");
 		// 直接返回檔案儲存的路徑,並將其構建成一個audio元素
		echo "<audio src='http://192.168.250.191/android_test/assets/upload/1.mp3' controls='controls'>";
	}
}
?>