我在Android应用中遇到了一个新错误,在调用时遇到空引用错误...
"currentAmplitude = mRecorder.getMaxAmplitude();"
在以下代码中:
public void useHandler() {
//setCurrentAmplitude();
handler = new Handler();
handler.postDelayed(runnable, 100);
}
private Runnable runnable = new Runnable() {
@Override
public void run() {
currentAmplitude = mRecorder.getMaxAmplitude();
Toast.makeText(getApplicationContext(), "Testing handler",
Toast.LENGTH_LONG).show();
TextView txtPowerLevel = (TextView) findViewById(R.id.txtPowerLevel);
txtPowerLevel.setText(Integer.toString(currentAmplitude));
handler.postDelayed(runnable, 100);
}
};
我在课堂顶部声明了当前的态度:
private int currentAmplitude;
我还是Java和Android的新手,在理解范围方面遇到了一些麻烦,应该在哪里宣布等等。所以我不禁想到我犯了一个非常明显的错误,但我花了好几个小时试图已经解决了这个问题,并且正在寻求帮助。
我主要尝试在这里和那里评论线条,看看会发生什么。如果我注释掉有问题的行,程序运行正常,只是没有我追求的功能。
我现在想要完成的是将当前幅度显示在textview中。主要是为了测试音频是否有效,但我稍后会将该文本视图用作一种计数器。我的相机预览在我的纹理视图上显示正常,并且在准备,启动或停止我的音频捕获时没有错误。我似乎无法让它向我展示振幅。
这是整个班级(如下)。如果你能发现我做错了什么,请告诉我。我也非常感谢为什么它不起作用的任何其他解释,以帮助我更好地理解代码,以便下次自己解决它。
public class DBZPowerUp extends AppCompatActivity implements TextureView.SurfaceTextureListener {
private MediaRecorder mRecorder = null;
private Handler handler = new Handler();
private Camera mCamera;
private int currentAmplitude;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dbzpowerup);
// Define the textureview in XML and apply the surface listener for camera preview
TextureView mTextureView = (TextureView) findViewById(R.id.textureView1);
mTextureView.setSurfaceTextureListener(this);
// Run methods to start audio capture
startAudioCapture();
// getAmplitude();
// Input the current amplitude level into the power level textview
//setCurrentAmplitude();
useHandler();
}
public void useHandler() {
//setCurrentAmplitude();
handler = new Handler();
handler.postDelayed(runnable, 100);
}
private Runnable runnable = new Runnable() {
@Override
public void run() {
currentAmplitude = mRecorder.getMaxAmplitude();
Toast.makeText(getApplicationContext(), "Testing handler",
Toast.LENGTH_LONG).show();
TextView txtPowerLevel = (TextView) findViewById(R.id.txtPowerLevel);
txtPowerLevel.setText(Integer.toString(currentAmplitude));
handler.postDelayed(runnable, 100);
}
};
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mCamera = Camera.open();
try {
mCamera.setPreviewTexture(surface);
mCamera.startPreview();
} catch(IOException e) {
Log.e("DBZ_", "Camera broke");
}
mCamera.setDisplayOrientation(90);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Ignored, Camera does all the work for us
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mCamera.stopPreview();
mCamera.release();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// Invoked every time there's a new Camera preview frame
}
public void startAudioCapture() {
if (mRecorder == null) {
MediaRecorder mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
mRecorder.setOutputFile("/dev/null");
try {
mRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mRecorder.start();
}
}
public void stopAudioCapture() {
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
/* private void setCurrentAmplitude() {
if (mRecorder.getMaxAmplitude() > 0) {
currentAmplitude = mRecorder.getMaxAmplitude();
} else {
currentAmplitude = 1;
}
}*/
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(runnable);
stopAudioCapture();
}
}
答案 0 :(得分:1)
您可以使用三星官方technical-doc执行此操作
Android AudioRecord类允许您将捕获的音频样本读入缓冲区。在这个例子中,我们使用每个样本16位的编码存储每个样本,在两个字节的短数组缓冲区中。我们使用均方根(RMS)计算振幅,其中计算值等于样本值的平方均值的平方根。然后,为了显示结果,我们创建了一个带有绿色到红色渐变的进度条,显示了音量。重新编码完成后,应用程序以.Wav文件中的PCM Wave格式保存原始数据。