I'm stuck on a new bug in my Android app, getting a null reference error when calling...
"currentAmplitude = mRecorder.getMaxAmplitude();"
in the following code:
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);
}
};
I have currentAmplitude declared at the top of my class as:
private int currentAmplitude;
I'm still new to Java and Android and have some trouble with understanding scope, and where things should be declared etc. So I can't help but think I've made a really obvious mistake but I spent hours trying to work this out already and am reaching out for help.
I've mostly tried commenting out lines here and there to see what happens. If I comment out the offending line, the program runs fine, just without the functionality I'm after.
What I'm trying to accomplish right now, is to have the current amplitude displayed in a textview. Mostly just to test audio is working, but I will later use that text view as a kind of counter. I have my camera preview displaying okay on my textureview, and no errors on preparing, starting or stopping my audio capture. I just can't seem to get it to show me the amplitude.
Here's the entire class (below). Please let me know if you can spot what I've done wrong. I'd also really appreciate any additional explanation of why it isn't working, to help me understand the code better to resolve it myself next time.
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();
}
}
Your mRecorder
object is null
In this code, you are creating a new MediaRecorder
object.
public void startAudioCapture() {
if (mRecorder == null) {
MediaRecorder mRecorder = new MediaRecorder();
}
Instead create and assign the newly created MediaRecorder
object to the globally declared mRecorder
variable.
Like this
public void startAudioCapture() {
if (mRecorder == null) {
mRecorder = new MediaRecorder();
}