Developing an Audio Recorder app

Hey people!

In this tutorial, we’ll develop a basic Audio capturing android application. This tutorial is the second part of the series in which we develop basic Android applications.

unnamed

You can find the previous article on Screen mirroring here: Screen mirroring android app

Let’s start developing our recorder app. The most common way to do this is through the MediaRecorder class. Let’s see the code now!

In our MainActivity.java file, we’ll instantiate myAudioRecorder from MedianRecorder class. We’ll provide it the audio source (Mic), give it the output format as 3Gpp and save it.

Read more about MediaRecorder: MediaRecorder


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 the Internal file storage. (take it as a personal task!)

We’ve added three buttons:

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. We will attach myAudioRecorder object to the onClickListener events of individual buttons. 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();

}

For PLAY, we’ll read the output file and play it through a MediaPlayer object. 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();

}

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. 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.

The next tutorial will be about developing a Photo Gallery android application.

Stay tuned!

Published by Aditya Rohilla

Graduate CS student at ASU | Ex - Samsung | Ex - Myntra. Highly enthusiastic about new technologies. Currently developing AI and ML applications2.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: