Android audio recording, part 1

by Krishnaraj Varma on December 5, 2010

Download source code of this article.

In Android we can record audio in two different ways; using MediaRecorder class and using AudioRecord class. Using MediaRecorder class is very easy but gives you less flexibility. AudioRecord class provides you more flexibility but is little bit complex. This article is about recording audio using MediaRecorder, I will explain the AudioRecord class in another article.

Using MediaRecorder class we can record the audio in two different formats, MediaRecorder.OutputFormat.THREE_GPP or MediaRecorder.OutputFormat.MPEG_4. In both cases the encoder should be MediaRecorder.AudioEncoder.AMR_NB. Till version 2.2, Android does not support other encoders. This link gives the details of media formats supported in Android.

To record an audio using MediaRecorder:

  1. Create an instance of MediaRecorder
  2. Set the audio source using setAudioSource() method
  3. Set output format using setOutputFormat() method
  4. Set Audio encoder using setAudioEncoder() method
  5. Set output file path using setOutputPath() method
  6. prepare using prepare() method
  7. start recording using start() method

The following code snippet starts audio recording:

recorder = new MediaRecorder();

recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("/sdcard/sample.3gp");

recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);

try {
	recorder.prepare();
	recorder.start();
} catch (IllegalStateException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}

And following code snippet stops recording:

recorder.stop();
recorder.reset();
recorder.release();

recorder = null;

Note that we have to reset and release the MediaRecorder object because it is a limited resource in Android, if it is not released other applications using MediaRecorder may not get this resource.

MediaRecorder class uses event listener interface to report any errors or warning occurred during recording session. There are two event listeners MediaRecorder.OnErrorListener and MediaRecorder.OnInfoListener. The MediaRecorder.OnErrorListener is used to report any errors during recording. It has the following method:

public void onError(MediaRecorder mr, int what, int extra)

This method is called when an error occurred, the first parameter is the MediaRecorder object, second one is the error code and third one is the extra information regarding the error occurred.

MediaRecorder.OnInfoListener is used to report any warning occurred. It has the following method:

public void onInfo(MediaRecorder mr, int what, int extra)

This method is called when any warning occurred during recording, the first parameter is the MediaRecorder object, second one is the warning code and third one is the extra information about the warning occurred.

The Audio Source can be one of the following values:

  1. MediaRecorder.AudioSource.DEFAULT – default source usually MIC
  2. MediaRecorder.AudioSource.MIC – Microphone
  3. MediaRecorder.AudioSource.VOICE_CALL – Voice call uplink and downlink source
  4. MediaRecorder.AudioSource.VOICE_DOWNLINK – Voice call downlink source
  5. MediaRecorder.AudioSource.VOICE_UPLINK – Voice call uplink source
  6. MediaRecorder.AudioSource.VOICE_RECOGNITION – Usually DEFAULT source

Even though we can set any one the above Audio Source, from my experience only MediaRecorder.AudioSource.MIC is working in my Nexus One with Android 2.2, all others are not working. If anyone can record using other sources please comment here.

Sample Application

The sample application is a simple one that records audio from MIC and stores the file in “/SDCard/AudioRecorder” folder with current milliseconds as the filename. A sample screen shot is displayed below:

Audio Recorder main screen Audio Recorder choose format screen

Hope this is piece of information is useful to you all.

{ 21 comments… read them below or add one }

rojy george December 13, 2010 at 1:02 pm

Hallo Sir,
Downloaded the source code and created a sample app installed in device it records audio from MIC, but the recorded file is not playing shows “player does not support this type of audio file” .what should be done so that it will play in device please help

Reply

Krishnaraj Varma December 14, 2010 at 2:17 pm

Hello Rojy, I am not sure why it is not playing in your device. Could you please check whether other 3GPP and MP4 files are playing, these formats are by the system.

Reply

Milind October 20, 2011 at 8:10 am

Can we record Voice Call also with this method if we use : MediaRecorder.AudioSource.VOICE_CALL in place of MediaRecorder.AudioSource.MIC ?
As per me when we select MediaRecorder.AudioSource.MIC then also it should work (only when input device is MIC) . In case if it is WIRED_HEADSET then MIC will not come into picture .
Please let me know your inputs on “VOICE_CALL” point .

Reply

mukund November 24, 2011 at 9:57 am

Hello sir, the file recorded are saved in amr format are not played, its give an error like “No suitable decoder module:
Player does not support the audio or video format “samr”.” so where is the problem?
Thanks in advance :)

Reply

SophieEvie December 21, 2010 at 11:08 am

hi ….its such a nice information and much more helpfull for those who are working with android. Android Application Development

Reply

Poonam April 4, 2011 at 1:38 am

Hello,
I am having a small issue with the Media Record class. When I call the start() method, the recorder starts recording after some delay. I have seen this happening on Android 2.3 devices. This issue does not appear on Android 1.6 or any version of Android emulators. Could you please confirm if you are seeing this issue with your hardware and if you have any solution for the same?

Thanks

Reply

Krishnaraj Varma April 10, 2011 at 7:16 am

Poonam, I checked on my Nexus One with 2.3.3 and didn’t found any delay. Can you tell whether you are getting a long delay? also can you check in other devices with 2.3 also?

Reply

hugh August 17, 2011 at 3:48 am

HI!
I was really happy to read what you post on this website.
I really wonder that I could make an app that records voice call
with my voice and the others’.
when I use those methods, I just can record my voice not
the others’
Could you help me with this code?

public class RecordingAudioActivity extends Activity {
private static final String AUDIO_RECORDER_FILE_EXT_3GP = “.3gp”;
private static final String AUDIO_RECORDER_FILE_EXT_MP4 = “.mp4″;
private static final String AUDIO_RECORDER_FILE_EXT_AMR = “.amr”;
private static final String AUDIO_RECORDER_FOLDER = “AudioRecorder”;
private Context context;
private MediaRecorder recorder = null;
private int currentFormat = 0;
private int output_formats[] = { MediaRecorder.OutputFormat.MPEG_4, MediaRecorder.OutputFormat.THREE_GPP };
private String file_exts[] = { AUDIO_RECORDER_FILE_EXT_MP4, AUDIO_RECORDER_FILE_EXT_3GP, AUDIO_RECORDER_FILE_EXT_AMR};
AudioManager audiomanager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = getApplicationContext();
audiomanager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);

setButtonHandlers();
enableButtons(false);
setFormatButtonCaption();
}

private void setButtonHandlers() {
((Button)findViewById(R.id.btnStart)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btnStop)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btnFormat)).setOnClickListener(btnClick);
}

private void enableButton(int id,boolean isEnable){
((Button)findViewById(id)).setEnabled(isEnable);
}

private void enableButtons(boolean isRecording) {
enableButton(R.id.btnStart,!isRecording);
enableButton(R.id.btnFormat,!isRecording);
enableButton(R.id.btnStop,isRecording);
}

private void setFormatButtonCaption(){
((Button)findViewById(R.id.btnFormat)).setText(getString(R.string.audio_format) + ” (” + file_exts[currentFormat] + “)”);
}

private String getFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);

if(!file.exists()){
file.mkdirs();
}

return (file.getAbsolutePath() + “/” + System.currentTimeMillis() + file_exts[currentFormat]);
}

private void startRecording(){
recorder = new MediaRecorder();

recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_DOWNLINK | MediaRecorder.AudioSource.VOICE_UPLINK);
//recorder.setOutputFormat(output_formats[currentFormat]);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getFilename());
//recorder.setAudioChannels(1);
//recorder.setAudioSamplingRate(44100);
//audiomanager.setSpeakerphoneOn(true);
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);

try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

private void stopRecording(){
if(null != recorder){
recorder.stop();
recorder.reset();
recorder.release();

recorder = null;
}
}

private void displayFormatDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
String formats[] = {“MPEG 4″, “3GPP”, “AMR”};

builder.setTitle(getString(R.string.choose_format_title))
.setSingleChoiceItems(formats, currentFormat, new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
currentFormat = which;
setFormatButtonCaption();

dialog.dismiss();
}
})
.show();
}

private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
@Override
public void onError(MediaRecorder mr, int what, int extra) {

}
};

private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {

}
};

private View.OnClickListener btnClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnStart:{

enableButtons(true);
startRecording();

break;
}
case R.id.btnStop:{

enableButtons(false);
stopRecording();

break;
}
case R.id.btnFormat:{
displayFormatDialog();

break;
}
}
}
};
}

Reply

sahap faras August 23, 2011 at 9:21 am

it gives an error when i clicked to the “Record” button, i downloaded the source code. i dont know whats happening.

Reply

sahap faras August 23, 2011 at 9:33 am

it’s about the permissions i’ve solved it.

Reply

Mathi June 16, 2012 at 1:21 pm

Can u please tell me what permissions to be added….?

Reply

Solanki Ranvir November 10, 2011 at 5:41 am

Hello to all of you.
I create my android application of streaming Radio.Now i am trying to record this streaming radio audio but i don’t know how it is done.which audio source i set instead of recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
So can any help me?

Reply

Alan November 12, 2011 at 11:56 pm

hello sahap, could you please tell me more about your solution? I am getting the same problem but I cannot find a way to fix it.

Reply

Rashi November 29, 2011 at 12:37 pm

Hello, can i start recording audio using Proximity Sensors? I mean when i bring my cell near mouth, it should start recording and after a certain time, it should stop? is it possible? I have found an option set max. duration for recording.. how can i do it? thanx in advance..

Reply

rohit December 1, 2011 at 6:16 am

Hi varma,
I downloaded the source code and run that one start button is working but When click the stop button it showing the force close error.

Reply

aru December 17, 2011 at 8:10 pm

hii is dr a way fr me to stream this captured audio real time instead of recording

Reply

krishna December 18, 2011 at 5:36 am

hi sahap faras, can you let me know the permission that you have given and where? please share the piece of change tht you did….
thanks in advance

Reply

pramod December 22, 2011 at 6:47 am

thks
its really helpful for me

Reply

john January 29, 2012 at 5:00 am

hello, after I pasted your code to eclipse, i get this error

The method onError(MediaRecorder, int, int) of type new MediaRecorder.OnErrorListener(){} must override a superclass method

this error I ge on every line @Override
public void onClick(DialogInterface dialog, int which) {
currentFormat = which;
setFormatButtonCaption();

Cpuld you help te by telling how to selve it?

thanks!

Reply

AuTi February 15, 2012 at 3:57 pm

Hi, I have a little problem with the MediaRecorder.Start() statement.
I’m develop a small application to record a call, but, when start to record the app stock in this state and I have to shut down the AVD, obviously, the file has no data.
This is the code of my application.

https://gist.github.com/1829663

PS: Very great site…goes to favorite bar :)

Reply

Hussien March 22, 2012 at 2:33 am

I disagree

Reply

Leave a Comment

 

Previous post:

Next post: