【问题标题】:Android timer seems to ignore .cancelAndroid 计时器似乎忽略了 .cancel
【发布时间】:2016-04-04 08:58:19
【问题描述】:

我正在构建一个 Android 应用程序,它会在打开某个 Activity 时录制声音。我已经在服务类中分离了记录功能。我一直在使用来自this 问题的答案,它有效。但是,我确实在再次停止计时器时遇到了一些麻烦!

ArrayList<Double> decibelList = new ArrayList<>();
private MediaRecorder mRecorder = null;
Timer timer = new Timer();
RecorderTask recorderTask;

public void startRecorder() {
    mRecorder = new MediaRecorder();
    mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    timer = new Timer();
    recorderTask = new RecorderTask(mRecorder);
    timer.scheduleAtFixedRate(recorderTask, 0, 400);
    mRecorder.setOutputFile("/dev/null");

    try {
        System.out.println("--MediaRecorder started--");
        mRecorder.prepare();
        mRecorder.start();
    } catch(IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private class RecorderTask extends TimerTask {
    private MediaRecorder recorder;

    public RecorderTask(MediaRecorder recorder) {
        this.recorder = recorder;
    }

    public void run() {
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                int amplitude = recorder.getMaxAmplitude();
                double amplitudeDb = 20 * Math.log10((double) Math.abs(amplitude));
                if (!String.valueOf(amplitudeDb).equals("-Infinity")) {
                    decibelList.add(amplitudeDb);
                }
                System.out.println("Current dB: " + amplitudeDb);
            }
        });
    }
}

public void stopRecorder() {
    if (mRecorder != null) {
        if (timer != null) {
            timer.cancel();
            timer.purge();
            timer = null;
        }
        try {
            mRecorder.stop();
            mRecorder.release();
            mRecorder = null;
        } catch (RuntimeException stopException){}
    }
}

然后在我的活动中的 onBackPressed、onPause 和 onStop 中执行 stopRecorder 函数。

如您所见,我尝试通过 timer.cancel(); 停止它。但尽管关闭了活动,它仍会继续运行。

【问题讨论】:

标签: android timer mediarecorder


【解决方案1】:

解决了我的问题。

事实证明我的取消确实有效,但我不小心启动了两个计时器!我通过添加一个检查我的计时器是否为空来解决了这个问题。

public void startRecorder() {
    mRecorder = new MediaRecorder();
    mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mRecorder.setAudioEncodingBitRate(16);
    mRecorder.setAudioSamplingRate(44100);
    if (timer == null) {
        timer = new Timer();
        recorderTask = new RecorderTask(mRecorder);
        timer.scheduleAtFixedRate(recorderTask, 0, 400);
    }
    mRecorder.setOutputFile("/dev/null");

    try {
        System.out.println("--MediaRecorder started--");
        mRecorder.prepare();
        mRecorder.start();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

以防万一有人想使用该代码。

非常感谢 cmets!他们帮助我优化了我的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2016-09-30
    • 2016-03-16
    • 2014-02-03
    • 2012-03-11
    • 2013-09-07
    • 2016-08-12
    相关资源
    最近更新 更多