2016-04-04 8 views
1

私は、特定のアクティビティが開かれたときにサウンドを記録するAndroidアプリケーションを構築しています。私は、サービスクラスの記録機能を分離しました。私はthis質問からの答えを使用しています、それは動作します。私はしかし、もう一度タイマーを停止するいくつかの問題があります!Androidのタイマーが無視されるようです。

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){} 
    } 
} 

stopRecorder関数は、自分のonBackPressed、onPause、onStopで実行されます。

ご覧のとおり、timer.cancel()を使用して停止してみました。アクティビティを終了しても引き続き実行されます。

+2

キャンセル機能は、実行中のタスクに影響しません。 "現在実行中のタスクがある場合は影響を受けません" http://developer.android.com/reference/java/util/Timer.html – Enpi

+1

javaDocsからも 'この呼び出しが発生したときにタスクが実行中の場合、タスクは完了まで実行しますが、再度実行されることはありません。https://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html#cancel() – Yazan

+0

@Enpi Right。私はタイマーを止める方法を提案していますか?私はあなたのリンクでそうする機能を見つけることができないようです。 –

答えて

1

解決しました。

私のキャンセルは実際にはうまくいきましたが、私は誤って2つのタイマーを開始しました!タイマーがnullの場合にチェックを追加して問題を解決しました。

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

誰でもコードを使用したい場合に備えてください。

コメントありがとうございます!彼らは私のコードを最適化するのに役立ちました。

関連する問題