Our Tutorial
Our tutorial app consists of two activities.
The first activity allows the user to record audio which is saved in a file in the external storage area. The second activity plays back that audio file.
Use the first activity to record audio and the second to play the audio back
Recording audio using the device’s microphone
The manifest: getting permission
You need permission to:
- Record audio
- Write to the external storage, where we want to save our recorded audio file
You’ll need to include these two
Start recording
You can register interfaces which are triggered by information and error events while you are recording.
We’ve included these interfaces in our startRecording() method.
The Information interface
Here’s the code for the MediaRecorder.OnInfoListener interface:
We register the MediaRecorder.OnInfoListener interface which triggers its onInfo() method when an informational event occurs while recording
The error interface
Here’s the code for the MediaRecorder.OnErrorListener interface:
We register the MediaRecorder.OnErrorListener interface which triggers its onError() method when an error occurs while recording
Here’s the remaining code of our startRecording() method:
Before you can start recording, you need to create a new MediaRecorder object and prepare it for recording by setting up the audio source, output format, file, and encoder
Note the following:
- setAudioSource – we set the source here for our audio recording. Must be called before setOutputFormat()
- MIC – we’re going to use the device’s microphone to record the audio
- setOutputFormat – we set the format of the output file here. Must be called after setAudioSource() and before prepare()
- THREE_GPP – 3GPP file format. You should always use the 3GPP format when using the AMR audio encoder
- setAudioEncoder – we set the audio encoder to be used for the recording here. Must be called after setOutputFormat() and before prepare()
- AMR_NB – the audio encoder we’ll use for our recording. It’s an audio compression format used for speech coding
- setOutputFile – we set the path for the file that will contain our recording. Must be called after setOutputFormat() but before prepare(). We pass the constant, FILE_NAME as the parameter. You may want to read Using Android’s file system for saving application data for more on using files
- prepare – prepares the encoder to begin capturing and encoding the audio. Called after setting up the audio source, encoder and file format but before start(). It throws two exceptions:
- IllegalStateException – thrown if prepare() is called after start() but before setOutputFormat()
- IOException – thrown if prepare() fails
- start – starts to capture and encode the audio to our file. Must be called after prepare(). It throws an IllegalStateException if called before prepare()
- setText – we set the text to indicate that we’re busy recording
Stop recording
Call stop() to stop recording:
Call release() after stopping the recording to free up all the resources used by the media recorder
Note the following:
- stop – stops the recording. Must be called after start()
- release - we release all resources associated with this MediaRecorder object – it’s good practice to call release() in the activity’s onPause() or onStop() methods if you no longer need the recorder. If you don’t, it continues to use the battery and may cause other problems too
- we use a try/catch statement to catch any exceptions:
- NullPointerException – thrown if stop() is called and the recorder has not been initialised
- IllegalStateException - thrown if stop() is called before start() is called
- setText – we set the text to display that we have stopped recording
Playing our recording
Managing the State
The MediaPlayer is State based. Certain methods can only be called when the player is in a certain state. Calling a method when the player is in the wrong state can throw an exception or cause some other unwanted behaviour.
State diagram
The media player is State based. You can only call certain methods when the player is in a certain state
Where are you saving the audio: Setting the data source
You can use the MediaPlayer to play audio and video files from these sources:
- local resources (e.g. Raw files)
- internal URI’s (e.g. Content Providers)
- External URL’s (for Streaming)
We use a file path to an external file, on the SD card for our source:
You must call setDataSource() when the MediaPlayer is in the Idle State. It’s best practice to catch the IOException and IllegalArgumentException exceptions when calling setDataSource()
Note the following:
- setDataSource must be called when the player is in the Idle State. It then transfers it into the Initialized State. It will throw an IllegalStateException if it’s called in any other state. setDataSource() also throws a number of other exceptions. It’s good practice to at least catch these two:
- IOException
- IllegalArgumentException
- FILE_NAME – a constant String containing the path to our saved audio file
Getting the player ready: Asynchronous preparation
The media player must be in the Prepared State before you can start playback by calling start(). It can take some time to fetch and decode data, so don’t call prepare() on the User Interface thread – your app may hang and possibly display the Application Not Responding dialog. Have look at Processes and Threads for more on threads.
There are two methods that you can use to get your media player into the Prepared State:
- prepare() – you have to take care of using a separate thread
- prepareAsync() – takes care of the threading and prepares the media in the background for you. We use an OnPreparedListener which executes onPrepared() when the preparation is finished
prepareAsync() takes care of preparing the MediaPlayer in the background for you
Note the following:
- prepareAsync – takes care of fetching and decoding the data for you in the background
- OnPreparedListener – an interface containing the onPrepared() method which is executed when the preparation is finished
- onPrepared – executed once the background preparation of the MediaPlayer is complete. The player is now in the Prepared State and we can start playback
- start – we start playback
Start Playing
Checking for errors
You can implement the MediaPlayer.OnErrorListener interface to handle any errors that occur during the asynchronous operations.
Other errors will throw exceptions when the method is called.
It’s good practice to register an OnErrorListener interface to handle errors during playback
Note the following:
- we register an OnErrorListener interface for our media player
- onError – executed if an error occurs during an asynchronous operation (other errors will throw an exception). The media player is then placed in the Error State
- it returns true if the error is handled
- it returns false if the error is not handled. The OnCompletionListener interface’s onCompletion() method will then be called
On completion
The MediaPlayer.OnCompletionListener interface executes its onCompletion() method when the playback has reached the end of the stream or due to an error.
onCompletion() is called when the playback reaches the end of the stream
Note the following:
- we register an OnCompletionListener interface for our media player
- onCompletion – called when:
- playback reaches the end of the stream
- OnErrorListener’s onError() method was unable to handle the error and returns false
- an asynchronous error occurred and we did not register an OnErrorListener interface
Stop Playing
You can pause and resume playback. You can also stop playback, putting the MediaPlayer into the Stopped State.
You can only restart a stopped player once it’s returned to the Prepared State.
Calling stop() in the wrong state throws an IllegalStateException exception
Note the following:
- null – check if the MediaPlayer has been initialised
- we enclose the call to stop() in a try/catch statement because it will throw an IllegalStateException exception if the player has not been initialised when stop() is called
Releasing the MediaPlayer
The media player uses valuable resources. You should release these resources once you’ve finished with the player.
You can release the resources in the app’s onStop() and onPause() methods (You may want to read, The Activity Lifecycle for more on the activity lifecycle) :
onPause() is called when the activity is placed in the background or is about to be destroyed
Note the following:
- null – we check if our media player exists and is initialised
- release – releases the resources used by the player
- null – we set our media player variable to null. We no longer need it so this will help the garbage collector identify it as reclaimable
Note that you can use a Service if you want the MediaPlayer to continue playing in the background. You may want to read, All about Services in this regard.
You may also want to check out, Using Android's SoundPool class: A Tutorial and Perfect sound using the Equalizer effect: a tutorial.
I hope that you have found this tutorial helpful.
This project was created using .
You can download the project files here
Are you using Eclipse or another IDE? Here's how you can use this project's Android Studio files.