我从getMaxAmplitude()看过各种各样的帖子,都用方法MediaRecorder解决了问题,但仍然无法解决我的问题。我想用分贝的声音幅度不断更新TextView。我试图通过使用调用此方法的函数每隔1秒钟运行一个处理程序来实现这一目标,但似乎MediaRecorder对象即使在初始化它之后也总是为null(我觉得很奇怪)。顺便说一句,我已经添加了在android中进行音频录制的所有必要权限。我需要在代码中进行哪些更改才能访问getMaxAmplitude()方法?
package com.inversepalindrome.sensorbox;
import com.cardiomood.android.controls.gauge.SpeedometerGauge;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Build;
import android.os.Handler;
import android.content.pm.PackageManager;
import android.widget.TextView;
import android.media.MediaRecorder;
import android.support.v4.app.ActivityCompat;
import android.widget.Toast;
import java.io.IOException;
import java.util.Locale;
public class SoundActivity extends AppCompatActivity {
private MediaRecorder mediaRecorder;
private SpeedometerGauge speedometer;
private TextView soundAmplitudeText;
private final int AUDIO_REQUEST_CODE = 200;
private final int AUDIO_RECORDING_DELAY = 1000;
private final double referenceAmplitude = 0.0001;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sound);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.RECORD_AUDIO,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, AUDIO_REQUEST_CODE);
}
speedometer = findViewById(R.id.speedometer);
speedometer.setLabelConverter(new SpeedometerGauge.LabelConverter() {
@Override
public String getLabelFor(double progress, double maxProgress) {
return String.format(Locale.US, "%.1f", progress);
}
});
speedometer.setMaxSpeed(120);
speedometer.setMajorTickStep(20);
speedometer.setMinorTicks(1);
speedometer.setLabelTextSize(32);
speedometer.addColoredRange(0, 40, Color.GREEN);
speedometer.addColoredRange(40, 80, Color.YELLOW);
speedometer.addColoredRange(80, 120, Color.RED);
soundAmplitudeText = findViewById(R.id.soundAmplitudeValueText);
}
@Override
public void onResume(){
super.onResume();
startRecording();
}
@Override
public void onPause(){
super.onPause();
stopRecording();
}
@Override
public void onRequestPermissionsResult(final int requestCode, String[] permissions, int[] grantResults) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestCode == AUDIO_REQUEST_CODE) {
startRecording();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
final double amplitude = getAmplitude();
speedometer.setSpeed(amplitude);
soundAmplitudeText.setText(String.format(Locale.US, "%.1f", amplitude));
handler.postDelayed(this, AUDIO_RECORDING_DELAY);
}
}, AUDIO_RECORDING_DELAY);
} else {
Toast.makeText(this, "No audio recording permissions given!", Toast.LENGTH_LONG).show();
}
}
}
private void startRecording(){
if(mediaRecorder != null)
{
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setOutputFile("/dev/null");
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void stopRecording(){
if(mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
}
private double getAmplitude(){
if(mediaRecorder != null){
final double maxAmplitude = mediaRecorder.getMaxAmplitude();
final double amplitude = 20 * Math.log10(maxAmplitude / referenceAmplitude);
return amplitude;
}
else{
return 0.0;
}
}
}
编辑:修复了一些指出的问题后,我的应用崩溃了 带有以下调试消息的getMaxAmplitudeCall:
1501-6480/? E/AudioFlinger: createRecordTrack_l() initCheck failed -12; no control block?
2019-01-18 15:23:54.983 2362-10949/com.google.android.googlequicksearchbox:search E/AudioRecord: AudioFlinger could not create record track, status: -12
2019-01-18 15:23:54.987 2362-10949/com.google.android.googlequicksearchbox:search E/AudioRecord-JNI: Error creating AudioRecord instance: initialization check failed with status -12.
2019-01-18 15:23:54.987 2362-10949/com.google.android.googlequicksearchbox:search E/android.media.AudioRecord: Error code -20 when initializing native AudioRecord object.
答案 0 :(得分:0)
if(mediaRecorder != null)
{
mediaRecorder = new MediaRecorder();
您可以向后检查。所以它永远不会初始化
答案 1 :(得分:0)
答案在我的评论中,但您的问题是您正在呼叫onPause停止录制,停止和释放MediaRecorder。如果您没有录制权限,可能会发生这种情况。当出现询问权限的对话框时,stopRecording被调用,因此您的录音机为空并被释放。
如果您已经具有权限,则不会发生。试试看。
此外,在startRecording方法中,检查您的媒体记录器是否为null。您是否拥有null的其他区别。