Audio Recorder With Media Controller

An ability to record yourself is one of the most accessible features of an Android device. There are plenty of situations where an individual may want to record a new idea, orinterviews or for any other purpose.The best part is that Android Studio provides inbuilt classes and libraries to create your own Audio Recorder...!

Here’s an example where I have created a customized Audio Recorder which allows you to record an audio & simultaneously save it, stop it and then finally play it. The play button incorporates a media controller which display a seek bar along with other controls.

The other important aspect of this project is the permission given at run time as well, otherwise the app doesn’t run on devices with API version above 23.

Also I have created a customized toolbar and a title. You can directly refer to the codes to understand how various styles and themes for toolbar are set.

Let us start creating the project. The step-wise procedure is given as follows –

  1. Create a new project in Android Studio:Specify an appropriate title for the project and select empty activity.

     

  2. Remove the toolbar from styles.xml as we have to set our own toolbar: Make the following changes in styles.xml file –
    <resources>
    
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    </style>
    
    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
    
    </resources>

     

The code snippet added above is two customized styles inside tag and two items inside tag.

      3. Design the xml layout of the respective Activity:The overall code for the layout is given as follows -

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.test.igeniusdev.audiorecorder.MainActivity"
android:id="@+id/rl">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:textAlignment="center"
app:popupTheme="@style/AppTheme.PopupOverlay">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Audio Recorder"
android:textSize="30dp"
android:layout_gravity="center"
android:id="@+id/toolbar_title"
android:textColor="#ffffff"/>

</android.support.v7.widget.Toolbar>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:textAlignment="center"
android:textSize="20dp"
android:typeface="serif"
android:textColor="#000000"
android:layout_marginTop="9dp"
android:textStyle="bold"
android:textIsSelectable="true" />

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/linearLayout"
android:layout_marginTop="40dp"
android:layout_marginLeft="9dp"
android:layout_marginRight="9dp"
android:layout_marginBottom="9dp">

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/l1"
android:layout_gravity="center">

<ImageView
android:layout_width="95dp"
android:layout_height="95dp"
android:id="@+id/imageView"
android:layout_gravity="center"
android:src="@drawable/record2"
android:layout_marginBottom="8dp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Record"
android:id="@+id/textView2"
android:layout_gravity="center"
android:textColor="#000000"
android:textSize="15dp" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/l2"
android:layout_gravity="center">

<ImageView
android:layout_width="95dp"
android:layout_height="95dp"
android:id="@+id/imageView2"
android:layout_gravity="center"
android:src="@drawable/stop"
android:layout_marginBottom="8dp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop"
android:id="@+id/textView3"
android:layout_gravity="center"
android:textColor="#000000"
android:textSize="15dp" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/l3"
android:layout_gravity="center">

<ImageView
android:layout_width="95dp"
android:layout_height="95dp"
android:id="@+id/imageView3"
android:layout_gravity="center"
android:src="@drawable/play2"
android:layout_marginBottom="8dp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play"
android:id="@+id/textView4"
android:layout_gravity="center"
android:textColor="#000000"
android:textSize="15dp" />
</LinearLayout>

</LinearLayout>

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/linearLayout"
android:layout_alignParentStart="true"
android:layout_marginBottom="8dp">

</LinearLayout>

</RelativeLayout>

 

     4. Take the following three permissions in Manifest file:

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

    5. Finally, code in the java class as follows:

public class MainActivityextends AppCompatActivityimplements MediaPlayer.OnPreparedListener, MediaController.MediaPlayerControl

{
    private LinearLayoutlrecord, lstop, lplay, lsave, lstopplay;
    String AudioSavePathInDevice= null;
    MediaRecordermediaRecorder;
    Random random ;
    String RandomAudioFileName= "ABCDEFGHIJKLMNOP";
    private MediaPlayermediaPlayer;
    private RelativeLayoutrl;
    private MediaControllermediaController;

    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    lrecord= (LinearLayout)findViewById(R.id.l1);
    lstop= (LinearLayout)findViewById(R.id.l2);
    lplay= (LinearLayout)findViewById(R.id.l3);
    rl= (RelativeLayout) findViewById(R.id.rl);

   lstop.setEnabled(false);
   lplay.setEnabled(false);
   random = new Random();
   
   lrecord.setOnClickListener(new View.OnClickListener()
   {
   @Override
   public void onClick(View v)
   {
     if(isRecordPermissionGranted() &&isStoragePermissionGranted())
        {

          AudioSavePathInDevice=
          Environment.getExternalStorageDirectory().getAbsolutePath() + "/" +
          CreateRandomAudioFileName(5) + "AudioRecording.3gp";
          MediaRecorderReady();

         try
          {
           mediaRecorder.prepare();
           mediaRecorder.start();
          }
         catch (Exception e)
           {
             e.printStackTrace();
           }

          lrecord.setEnabled(false);
          lstop.setEnabled(true);

          Toast.makeText(MainActivity.this, "Recording started", Toast.LENGTH_LONG).show();
        }
   else
        {
     Toast.makeText(MainActivity.this, "Granting permission", Toast.LENGTH_LONG).show();
                }

            }
        });


  lstop.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
   try {
      mediaRecorder.stop();
       } 
   catch (Exception e) {
      e.printStackTrace();
       }
   lstop.setEnabled(false);
   lplay.setEnabled(true);
   lrecord.setEnabled(true);

  Toast.makeText(MainActivity.this, "Recording Completed", Toast.LENGTH_LONG).show();
            }
        });


  lplay.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) throws IllegalArgumentException,
  SecurityException, IllegalStateException
    {
      lstop.setEnabled(false);
      lrecord.setEnabled(true);
      mediaPlayer= new MediaPlayer();
      mediaController= new MediaController(MainActivity.this);
      mediaPlayer.setOnPreparedListener(MainActivity.this);
 try
 {
     mediaPlayer.setDataSource(AudioSavePathInDevice);
     mediaPlayer.prepare();
  }
catch (Exception e)
  {
    e.printStackTrace();
  }

 mediaPlayer.start();
 Toast.makeText(MainActivity.this, "Recording Playing",Toast.LENGTH_LONG).show();
            }
        });
    }

public  booleanisStoragePermissionGranted()
    {
     if (Build.VERSION.SDK_INT>= 23)
        {
         if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
            {
              return true;
            }
        else
           {
             ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
             return false;
            }
        }
   else
      {
        return true;
        }
    }

public  booleanisRecordPermissionGranted()
    {
if (Build.VERSION.SDK_INT>= 23)
        {
if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED)
            {
return true;
            }
else
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
return false;
            }
        }
else
{
return true;
        }
    }

public void MediaRecorderReady()
    {
        mediaRecorder= new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
        mediaRecorder.setOutputFile(AudioSavePathInDevice);
    }

public String CreateRandomAudioFileName(intstring)
    {
      StringBuilderstringBuilder = new StringBuilder( string );
      inti = 0 ;
      while(i< string ) {
         stringBuilder.append(RandomAudioFileName.
         charAt(random.nextInt(RandomAudioFileName.length())));
          i++ ;
        }
   return stringBuilder.toString();
    }
@Override
public void onPrepared(MediaPlayermp)
    {
mediaController.setMediaPlayer(this);
mediaController.setAnchorView(findViewById(R.id.rl));

handler.post(new Runnable() {
public void run() {
mediaController.setEnabled(true);
mediaController.show();
            }
        });
    }
@Override
public booleanonTouchEvent(MotionEvent event)
    {
      mediaController.show();
      return false;
    }

@Override
public void start() {
      mediaPlayer.start();
    }

@Override
public void pause() {
     mediaPlayer.pause();
    }

@Override
public intgetDuration() {
     return mediaPlayer.getDuration();
    }

@Override
public intgetCurrentPosition()
    {
      return mediaPlayer.getCurrentPosition();
    }
@Override
public void seekTo(intpos) {
  mediaPlayer.seekTo(pos);
    }

@Override
public booleanisPlaying() {
  return mediaPlayer.isPlaying();
    }

@Override
public intgetBufferPercentage() {
  return 0;
    }

@Override
public booleancanPause() {
  return true;
    }

@Override
public booleancanSeekBackward() {
  return true;
    }

@Override
public booleancanSeekForward() {
   return true;
    }

@Override
public intgetAudioSessionId() {
  return 0;
    }
}

Now run the project and record as many as audios you fancy…! You can fetch the recorded audios from your sd card or internal memory afterwards and listen to them as you like.

The output of the project is shown as follows –

 

Let's Think together, Say Something !