Search code examples
androidparameter-passingaudio-recordingandroid-audiomanageraudio-player

Record and Save Audio in One Activity and Play back Audio in Another Activity


In my App with many activities, I am trying to make a recording in one activity and store it in the phone files. Then in another activity, I want to play that file back. I think I may have a problem with with how I am saving the original file because it crashes on the second activity when it wants to read the file. I am not sure how to save in one activity and then read that audio file in the next activity. I have included what I thought was relevant code from both activities.

//This is the Activity that simply records and then saves the audio file

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Context mContext = getApplicationContext();
        createTempFile("Status_Recorder.txt", "INPROGRESS");

         /*
          * Create the file where the audio tone that is recorded will be saved
          *
          */
        try{
            FileOutputStream fOut = openFileOutput("audio_test_right.3gp" , MODE_WORLD_READABLE);

        }catch(IOException e) {
            e.printStackTrace();
            exit_function();
        }

        path = mContext.getFilesDir()+"/audio_test_right.3gp";

        start_recording();
}


    //Method to Start the Recording
    private void start_recording() {
        //Intialize the recorder
        try{
        speaker_recorder = new MediaRecorder();
        speaker_recorder.reset();
        } catch(Exception e){
            Log.e(log_tag,"Recorder Initialization Failed");
            createTempFile("Status.txt", "COMPLETED-RECORDER FAILED");
        }

        //Setting for the Recorder
        try{
        Log.i(log_tag,"Setting the recorder");
        speaker_recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        speaker_recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        speaker_recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        speaker_recorder.setOutputFile(path);
        } catch(Exception e){
            Log.e(log_tag,"Recording Settings Failed");
            createTempFile("Status.txt", "COMPLETED-RECORDER FAILED");
        }
        //Prepare the Recorder
        try{
            Log.i(log_tag,"Preparing the Recorder");
            speaker_recorder.prepare();
        } catch(Exception e){
            Log.e(log_tag,"Recording failed");
            createTempFile("Status.txt", "COMPLETED-RECORDER FAILED");
            exit_function();
        }

        //Start the Recorder
        try {
            Log.i(log_tag,"Starting the recorder");
            title_text = ((TextView) findViewById(R.id.textView));
            title_text.setTextColor(Color.RED);
            title_text.setText("RECORDING");
            speaker_recorder.start();
//            Thread.sleep(10000);
            mHandler.postDelayed(new Runnable() {
                public void run() {
                    createTempFile("Status_Recorder.txt", "COMPLETED-RECORDER FAILED");
                    exit_function();
                }
            }, timer);

        } catch (Exception e) {
            Log.e(log_tag,"Recorder start failed");
            createTempFile("Status.txt", "COMPLETED-RECORDER FAILED");
            exit_function();
        }

}

    private void exit_function() {
        if (speaker_recorder != null) {
            speaker_recorder.release();
        }
        onDestroy();
    }

    @Override
    /*
     * (non-Javadoc)
     * @see android.app.Activity#onDestroy()
     * Function invoked before we exit the application . Reset all the volume
     * and stream values in this function
     */
    protected void onDestroy() {
        Log.i(log_tag,"Entered onDestroy()");
        super.onDestroy();
        this.finish();

    }

    /*
     * Function to create the a text file in the application directory context. This function
     * takes the file name and the string that is to be written in it as the input. This function is invoked
     * to create the Result.txt file.
     */
    private void createTempFile(String filename, String text) {

        try {
            FileOutputStream fOut = openFileOutput(filename , MODE_WORLD_READABLE);
            OutputStreamWriter osw = new OutputStreamWriter(fOut);
            osw.write(text);
            osw.flush();
            osw.close();

        } catch(IOException e) {
            e.printStackTrace();
        }

    }

//This is the Second Activity, but it Crashes when it gets to the mp.setDataSource(path); because I guess it cant find the path

 private void playSound(boolean speakers) {
        mContext = getApplicationContext();
//        audioManager.setMicrophoneMute(true);
        path = mContext.getFilesDir() + "/audio_test_right.3gp";
        audioManager.setSpeakerphoneOn(true);
        try {
            mp.setDataSource(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (speakers) {
            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);

        } else {
            mp.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);

        }
        mp.start();
        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                createTempFile("Status_RightSpeaker.txt", "COMPLETED");
                exit_function();
            }
        });
    }


    }

Solution

  • Ok, so i have a working code for your question

    This method when supplied with true will start recording else it will stop recording. So you can do this on your first activity

    private void startOrStopRecording(boolean record){
        if (record) {
            // Record the audio
            mMediaRecorder = new MediaRecorder();
            mMediaRecorder.reset();
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mMediaRecorder.setOutputFile(getFilesDir().getAbsolutePath() + "/audio_test.3gp");
    
            try {
                mMediaRecorder.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            mMediaRecorder.start();
        }else{
            // Stop recording
            if (mMediaRecorder != null){
                mMediaRecorder.stop();
                mMediaRecorder.release();
                mMediaRecorder = null;
            }
        }
    }
    

    This method when supplied with true starts to play the sound else stop. So you can implement it on your Second Activity

    NOTE String mFile = getFilesDir().getAbsolutePath() + "/audio_test.3gp";

    private  void playOrStop(boolean play){
        mPlayer = new MediaPlayer();
        try{
            if (play){
                mPlayer.setDataSource(mFile);
                mPlayer.prepare();
                mPlayer.start();
            }else {
                mPlayer.stop();
                mPlayer.release();
                mPlayer = null;
            }
        }catch (IOException e){
            Log.e("Mtali", e.getMessage());
        }
    }
    

    Be sure to add the permission

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    

    B.O.N.U.S

    You can use ToggleButton to

    START & STOP RECORDING

    JAVA

    final ToggleButton recordButton = (ToggleButton) findViewById(R.id.record_button);
    recordButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            startOrStopRecording(isChecked);
        }
    });
    

    XML

    <ToggleButton
        android:id="@+id/record_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textOff="@string/start_playback_string"
        android:textOn="@string/stop_playback_string"/>
    

    START AND STOP PLAYING

    JAVA

    ToggleButton button = (ToggleButton) findViewById(R.id.play_button);
    button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            playOrStop(isChecked);
        }
    });
    

    XML

    <ToggleButton
            android:id="@+id/play_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:textOff="@string/start_playback_string"
            android:textOn="@string/stop_playback_string"/>