Developing an Audio recorder app

Aditya Rohilla
MindOrks
Published in
5 min readApr 15, 2018

In this tutorial, we’ll develop a basic Audio capturing android application. It works similar to the native Android recorder application but has a very simple User Interface.

NOTE: This tutorial is meant for beginners and newbie Android developers. I’m assuming you are already familiar with some basic Android programming. If not, head to : Build your first app

You’ll learn about MediaRecorder class, how to take user-permissions (in Android M and above) and how to access external storage on android.

Use this icon for your application

Let’s start developing!

The most common way to record media is through the MediaRecorder class. In our MainActivity.java file, we’ll instantiate myAudioRecorder from MedianRecorder class. We’ll provide it the audio source (Mic) and give it output format as 3Gpp. A location in External storage is provided as output for storing audio.

private MediaRecorder myAudioRecorder;output = Environment.getExternalStorageDirectory().getAbsolutePath() + "/myrecording.3gp";myAudioRecorder = new MediaRecorder();myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);myAudioRecorder.setOutputFile(output);

Note: With every new recording, the previous one will get deleted as every recording is written in the same file.

In case you want to store all the files, you can save them in separate files. (take it as a personal task!)

Three buttons will be used:

1) START

2) STOP

3) PLAY

start = (Button)findViewById(R.id.button1);stop = (Button) findViewById(R.id.button2);play = (Button)findViewById(R.id.button3);start.setOnClickListener(this);stop.setOnClickListener(this);play.setOnClickListener(this);

Listener function:

@Override public void onClick(View v){switch (v.getId()){case R.id.button1:start(v);break;case R.id.button2:stop(v);break;case R.id.button3:try {play(v);}catch (IOException e){Log.i("IOException", "Error in play");}break;default:break;}}

Intuitively, the buttons perform as they are named. Now we will attach myAudioRecorder object to the onClickListener events of individual buttons to start and store the recording. For START and STOP:

public void start(View view){try{myAudioRecorder.prepare();myAudioRecorder.start();}catch (IllegalStateException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}start.setEnabled(false);stop.setEnabled(true);Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_SHORT).show();}public void stop(View view){myAudioRecorder.stop();myAudioRecorder.release();myAudioRecorder = null;stop.setEnabled(false);play.setEnabled(true);Toast.makeText(getApplicationContext(), "Audio recorded successfully", Toast.LENGTH_SHORT).show();}

A toast shows “Recording started” when the recording starts. Similarly we see a toast when the recording is saved. For PLAY, we’ll read the output file and play it through a MediaPlayer object. Again a toast is displayed for playing audio. We need to add try-catch blocks at various places to avoid any crashes.

public void play(View view) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {MediaPlayer m = new MediaPlayer();m.setDataSource(output);m.prepare();m.start();Toast.makeText(getApplicationContext(), "Playing audio", Toast.LENGTH_SHORT).show();}

In the UI, we will simply add three buttons as stated above. The activity_main.xml file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.india.recorder.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:text="Start"
android:id="@+id/button1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="175dp"
android:text="Stop"
android:id="@+id/button2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="300dp"
android:text="Play"
android:id="@+id/button3"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome to Recorder!"
android:layout_centerHorizontal="true"
android:fontFamily="sans-serif"
android:layout_marginTop="400dp"
android:textSize="25dp"
android:textColor="#008080"/>
</RelativeLayout>

We’ll need user permissions for accessing MIC and the storage, so we’ll add permissions in Android_Manifest.xml

NOTE: Permissions have changed on Android M. Permissions are now requested at runtime as opposed to install time previous to Android M.

To curb this problem we’ll add a check in our code to find the version of Android mobile we are working with and act accordingly.

@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);switch (requestCode){case 200:permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;permissionToWriteAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;break;}if (!permissionToRecordAccepted ) MainActivity.super.finish();if (!permissionToWriteAccepted ) MainActivity.super.finish();}

Add the required permissions in Android.manifest for record_audio and file_storage.

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

Now build the project and run the app. It should ask for permissions when you open it for the first time.

Everything should work as expected.

The complete MainActivity.java looks like:

package com.example.india.recorder;import android.Manifest;import android.content.pm.PackageManager;import android.media.MediaPlayer;import android.media.MediaRecorder;import android.os.Build;import android.os.Environment;import android.support.annotation.NonNull;import android.support.v4.app.ActivityCompat;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.View;import android.widget.Button;import android.widget.Toast;import java.io.IOException;public class MainActivity extends AppCompatActivity implements View.OnClickListener {public static final int RECORD_AUDIO = 0;private MediaRecorder myAudioRecorder;private String output = null;private Button start, stop, play;private boolean permissionToRecordAccepted = false;private boolean permissionToWriteAccepted = false;private String [] permissions = {"android.permission.RECORD_AUDIO", "android.permission.WRITE_EXTERNAL_STORAGE"};@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);int requestCode = 200;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {requestPermissions(permissions, requestCode);}start = (Button)findViewById(R.id.button1);stop = (Button) findViewById(R.id.button2);play = (Button)findViewById(R.id.button3);start.setOnClickListener(this);stop.setOnClickListener(this);play.setOnClickListener(this);stop.setEnabled(false);play.setEnabled(false);output = Environment.getExternalStorageDirectory().getAbsolutePath() + "/myrecording.3gp";myAudioRecorder = new MediaRecorder();myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);myAudioRecorder.setOutputFile(output);}@Override public void onClick(View v){switch (v.getId()){case R.id.button1:start(v);break;case R.id.button2:stop(v);break;case R.id.button3:try {play(v);}catch (IOException e){Log.i("IOException", "Error in play");}break;default:break;}}@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);switch (requestCode){case 200:permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;permissionToWriteAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;break;}if (!permissionToRecordAccepted ) MainActivity.super.finish();if (!permissionToWriteAccepted ) MainActivity.super.finish();}public void start(View view){try{myAudioRecorder.prepare();myAudioRecorder.start();}catch (IllegalStateException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}start.setEnabled(false);stop.setEnabled(true);Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_SHORT).show();}public void stop(View view){myAudioRecorder.stop();myAudioRecorder.release();myAudioRecorder = null;stop.setEnabled(false);play.setEnabled(true);Toast.makeText(getApplicationContext(), "Audio recorded successfully", Toast.LENGTH_SHORT).show();}public void play(View view) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {MediaPlayer m = new MediaPlayer();m.setDataSource(output);m.prepare();m.start();Toast.makeText(getApplicationContext(), "Playing audio", Toast.LENGTH_SHORT).show();}}

For enhancing the application (and your skills) more, you can use the Audio icon above as Start/Stop button such that on one tap it starts recording and on next tap it stops. You can use a different button for playing the audio.

If there’s any doubt, leave a comment.

In the future posts, I’m planning to write tutorials to develop comparatively more complex android applications.

Find more articles and tutorials at {the.Random (developer) ;}

Stay tuned!

--

--