Android:getMaxAmplitude()的空引用;

时间:2015-10-08 07:07:41

标签: android android-mediarecorder

我在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();
    }
}

1 个答案:

答案 0 :(得分:1)

您可以使用三星官方technical-doc执行此操作

  

Android AudioRecord类允许您将捕获的音频样本读入缓冲区。在这个例子中,我们使用每个样本16位的编码存储每个样本,在两个字节的短数组缓冲区中。我们使用均方根(RMS)计算振幅,其中计算值等于样本值的平方均值的平方根。然后,为了显示结果,我们创建了一个带有绿色到红色渐变的进度条,显示了音量。重新编码完成后,应用程序以.Wav文件中的PCM Wave格式保存原始数据。

enter image description here