1f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch/*
2f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * Copyright (C) 2011 The Android Open Source Project
3f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch *
4f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * Licensed under the Apache License, Version 2.0 (the "License");
5f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * you may not use this file except in compliance with the License.
6f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * You may obtain a copy of the License at
7f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch *
8f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch *      http://www.apache.org/licenses/LICENSE-2.0
9f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch *
10f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * Unless required by applicable law or agreed to in writing, software
11f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * distributed under the License is distributed on an "AS IS" BASIS,
12f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * See the License for the specific language governing permissions and
14f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * limitations under the License.
15f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch */
16f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch
1745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectpackage com.android.soundrecorder;
1845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
1945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport java.io.File;
2045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport java.io.IOException;
2145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
22615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Triviimport android.content.Context;
23615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Triviimport android.media.AudioManager;
2445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.media.MediaPlayer;
2545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.media.MediaRecorder;
2645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.media.MediaPlayer.OnCompletionListener;
2745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.media.MediaPlayer.OnErrorListener;
2845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.os.Bundle;
2945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.os.Environment;
3045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.util.Log;
3145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
3245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectpublic class Recorder implements OnCompletionListener, OnErrorListener {
3345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    static final String SAMPLE_PREFIX = "recording";
3445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    static final String SAMPLE_PATH_KEY = "sample_path";
3545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    static final String SAMPLE_LENGTH_KEY = "sample_length";
3645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
3745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public static final int IDLE_STATE = 0;
3845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public static final int RECORDING_STATE = 1;
3945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public static final int PLAYING_STATE = 2;
4045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
4145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    int mState = IDLE_STATE;
4245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
4345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public static final int NO_ERROR = 0;
4445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public static final int SDCARD_ACCESS_ERROR = 1;
4545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public static final int INTERNAL_ERROR = 2;
46615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi    public static final int IN_CALL_RECORD_ERROR = 3;
4745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
4845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public interface OnStateChangedListener {
4945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        public void onStateChanged(int state);
5045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        public void onError(int error);
5145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
5245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    OnStateChangedListener mOnStateChangedListener = null;
5345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
5445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    long mSampleStart = 0;       // time at which latest record or play operation started
5545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    int mSampleLength = 0;      // length of current sample
5645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    File mSampleFile = null;
5745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
5845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    MediaRecorder mRecorder = null;
5945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    MediaPlayer mPlayer = null;
6045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
6145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public Recorder() {
6245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
6345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
6445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void saveState(Bundle recorderState) {
6545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        recorderState.putString(SAMPLE_PATH_KEY, mSampleFile.getAbsolutePath());
6645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        recorderState.putInt(SAMPLE_LENGTH_KEY, mSampleLength);
6745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
6845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
6945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public int getMaxAmplitude() {
7045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mState != RECORDING_STATE)
7145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return 0;
7245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        return mRecorder.getMaxAmplitude();
7345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
7445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
7545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void restoreState(Bundle recorderState) {
7645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        String samplePath = recorderState.getString(SAMPLE_PATH_KEY);
7745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (samplePath == null)
7845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
7945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        int sampleLength = recorderState.getInt(SAMPLE_LENGTH_KEY, -1);
8045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (sampleLength == -1)
8145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
8245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
8345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        File file = new File(samplePath);
8445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (!file.exists())
8545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
8645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mSampleFile != null
8745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project                && mSampleFile.getAbsolutePath().compareTo(file.getAbsolutePath()) == 0)
8845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
8945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
9045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        delete();
9145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mSampleFile = file;
9245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mSampleLength = sampleLength;
9345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
9445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        signalStateChanged(IDLE_STATE);
9545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
9645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
9745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void setOnStateChangedListener(OnStateChangedListener listener) {
9845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mOnStateChangedListener = listener;
9945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
10045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
10145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public int state() {
10245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        return mState;
10345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
10445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
10545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public int progress() {
10645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mState == RECORDING_STATE || mState == PLAYING_STATE)
10745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return (int) ((System.currentTimeMillis() - mSampleStart)/1000);
10845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        return 0;
10945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
11045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
11145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public int sampleLength() {
11245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        return mSampleLength;
11345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
11445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
11545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public File sampleFile() {
11645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        return mSampleFile;
11745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
11845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
11945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    /**
12045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project     * Resets the recorder state. If a sample was recorded, the file is deleted.
12145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project     */
12245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void delete() {
12345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        stop();
12445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
12545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mSampleFile != null)
12645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mSampleFile.delete();
12745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
12845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mSampleFile = null;
12945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mSampleLength = 0;
13045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
13145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        signalStateChanged(IDLE_STATE);
13245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
13345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
13445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    /**
13545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project     * Resets the recorder state. If a sample was recorded, the file is left on disk and will
13645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project     * be reused for a new recording.
13745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project     */
13845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void clear() {
13945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        stop();
14045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
14145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mSampleLength = 0;
14245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
14345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        signalStateChanged(IDLE_STATE);
14445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
14545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
146615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi    public void startRecording(int outputfileformat, String extension, Context context) {
14745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        stop();
14845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
14945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mSampleFile == null) {
15045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            File sampleDir = Environment.getExternalStorageDirectory();
15145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            if (!sampleDir.canWrite()) // Workaround for broken sdcard support on the device.
15245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project                sampleDir = new File("/sdcard/sdcard");
15345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
15445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            try {
15545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project                mSampleFile = File.createTempFile(SAMPLE_PREFIX, extension, sampleDir);
15645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            } catch (IOException e) {
15745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project                setError(SDCARD_ACCESS_ERROR);
15845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project                return;
15945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            }
16045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        }
16145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
16245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mRecorder = new MediaRecorder();
16345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
16445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mRecorder.setOutputFormat(outputfileformat);
16545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
16645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mRecorder.setOutputFile(mSampleFile.getAbsolutePath());
16745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
16845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        // Handle IOException
16945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        try {
17045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mRecorder.prepare();
17145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        } catch(IOException exception) {
17245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            setError(INTERNAL_ERROR);
17345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mRecorder.reset();
17445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mRecorder.release();
17545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mRecorder = null;
17645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
17745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        }
178615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi        // Handle RuntimeException if the recording couldn't start
179615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi        try {
180615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi            mRecorder.start();
181615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi        } catch (RuntimeException exception) {
182615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi            AudioManager audioMngr = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
183c4deebf0a7650448a95986d675fccb7d8a3ceadbJean-Michel Trivi            boolean isInCall = ((audioMngr.getMode() == AudioManager.MODE_IN_CALL) ||
184c4deebf0a7650448a95986d675fccb7d8a3ceadbJean-Michel Trivi                    (audioMngr.getMode() == AudioManager.MODE_IN_COMMUNICATION));
185615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi            if (isInCall) {
186615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi                setError(IN_CALL_RECORD_ERROR);
187615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi            } else {
188615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi                setError(INTERNAL_ERROR);
189615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi            }
190615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi            mRecorder.reset();
191615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi            mRecorder.release();
192615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi            mRecorder = null;
193615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi            return;
194615384c62e2906613590e6f33a37f7dfe4276a59Jean-Michel Trivi        }
19545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mSampleStart = System.currentTimeMillis();
19645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        setState(RECORDING_STATE);
19745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
19845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
19945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void stopRecording() {
20045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mRecorder == null)
20145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
20245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
20345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mRecorder.stop();
20445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mRecorder.release();
20545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mRecorder = null;
20645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
20745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mSampleLength = (int)( (System.currentTimeMillis() - mSampleStart)/1000 );
20845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        setState(IDLE_STATE);
20945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
21045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
21145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void startPlayback() {
21245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        stop();
21345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
21445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mPlayer = new MediaPlayer();
21545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        try {
21645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mPlayer.setDataSource(mSampleFile.getAbsolutePath());
21745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mPlayer.setOnCompletionListener(this);
21845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mPlayer.setOnErrorListener(this);
21945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mPlayer.prepare();
22045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mPlayer.start();
22145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        } catch (IllegalArgumentException e) {
22245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            setError(INTERNAL_ERROR);
22345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mPlayer = null;
22445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
22545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        } catch (IOException e) {
22645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            setError(SDCARD_ACCESS_ERROR);
22745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mPlayer = null;
22845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
22945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        }
23045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
23145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mSampleStart = System.currentTimeMillis();
23245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        setState(PLAYING_STATE);
23345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
23445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
23545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void stopPlayback() {
23645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mPlayer == null) // we were not in playback
23745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
23845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
23945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mPlayer.stop();
24045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mPlayer.release();
24145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mPlayer = null;
24245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        setState(IDLE_STATE);
24345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
24445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
24545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void stop() {
24645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        stopRecording();
24745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        stopPlayback();
24845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
24945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
25045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public boolean onError(MediaPlayer mp, int what, int extra) {
25145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        stop();
25245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        setError(SDCARD_ACCESS_ERROR);
25345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        return true;
25445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
25545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
25645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void onCompletion(MediaPlayer mp) {
25745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        stop();
25845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
25945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
26045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    private void setState(int state) {
26145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (state == mState)
26245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            return;
26345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
26445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mState = state;
26545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        signalStateChanged(mState);
26645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
26745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
26845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    private void signalStateChanged(int state) {
26945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mOnStateChangedListener != null)
27045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mOnStateChangedListener.onStateChanged(state);
27145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
27245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
27345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    private void setError(int error) {
27445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mOnStateChangedListener != null)
27545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mOnStateChangedListener.onError(error);
27645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
27745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project}
278