Follow this blog:
RSS
Email Alert

Android App Builder

Rock and roll with Android’s media recorder

Takeaway: What does Bon Jovi have to do with Android coding? Find out in this media recorder tutorial by William J. Francis.

I have a son who is turning fourteen in a few weeks. He is every bit as much into gadgets and in particular Android phones as me; however, we don’t always see eye to eye on what is “cool.” Take for instance the app Songify — my son loves it, and he cranks out half a dozen “songs” on the car ride from the house to the grocery. And he’s not alone in his obsession. The app currently touts over a million downloads in Google Play.

If you’re not familiar with the premise of the app, the tag line says it all: “turn speech into music.” Just don’t set your internal bar too high for the resulting “music.” It’s entertaining — let’s leave it at that. With the immense popularity in the last 30 days of Songify and similar apps, I’ve seen a new surge of questions in the Android forums related to recording voice, so I figured what better subject to tackle this week in my post. You can follow along step by step tutorial, or download and import the entire project.

1. Start a new Android project in Eclipse. Target Android 1.6 or higher. Be sure to change the startup activity name to Main.java.

2. Add a couple of permissions to the manifest. We require access to the SD file system, as well as the media recorder.

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.authorwjf.voice_rec"
 android:versionCode="1"
 android:versionName="1.0" >
<uses-sdk android:minSdkVersion="4" />
 <uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:icon="@drawable/ic_launcher"
 android:label="@string/app_name" >
<activity
android:name=".Main"
 android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

3. Create a simple table layout in the /res/layout folder. The UI for our demo consists of two buttons and a label.

Main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:stretchColumns="*">
<TableRow>
<TextView
android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Voice Recorder Demo"
android:layout_span="2"
 android:layout_gravity="center"
 android:padding="12dip"/>
</TableRow>
<TableRow>
<Button
android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:id="@+id/record_button"
 android:text="record"
 android:layout_margin="12dip"/>
<Button
android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:id="@+id/play_back_button"
 android:text="play"
 android:layout_margin="12dip"/>
</TableRow>
</TableLayout>

4. We are ready for the /src/Main.java file. Let’s start by declaring some class level variables and wiring up our buttons in the on create override.

Main.java
package com.authorwjf.voice_rec;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class Main extends Activity implements OnClickListener {
MediaRecorder mRecorder = new MediaRecorder();
MediaPlayer mPlayer = new MediaPlayer();
boolean isRecording = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.play_back_button).setOnClickListener(this);
findViewById(R.id.record_button).setOnClickListener(this);
}
}

5. We have come to the heart of our code — the on-click handler. This is where we will do the recording and the playback.

Main.java
@Override
public void onClick(View v) {
mPlayer.stop();
switch (v.getId()) {
case R.id.play_back_button:
if (!isRecording && !mPlayer.isPlaying()) {
try {
mPlayer.reset();
mPlayer.setDataSource("/sdcard/audio_demo.3gp");
mPlayer.prepare();
mPlayer.start();
} catch (Exception e) {
Toast.makeText(this, "Error playing back audio.",Toast.LENGTH_SHORT).show();
}
}
break;
case R.id.record_button:
if (isRecording) {
isRecording = false;
((Button)(findViewById(R.id.record_button))).setText("record");
mRecorder.reset();
} else {
try {
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile("/sdcard/audio_demo.3gp");
mRecorder.prepare();
mRecorder.start();
((Button)(findViewById(R.id.record_button))).setText("stop");
isRecording = true;
} catch (Exception e) {
Toast.makeText(this, "Error starting recorder.",Toast.LENGTH_SHORT).show();
}
}
break;
}
}

6. We need to handle cleaning up our media recorder and playback objects when the activity gets destroyed — this keeps the app from crashing or leaking resources. Note: The app doesn’t attempt to continue recording through an orientation change.

Main.java
@Override
public void onDestroy() {
if (isRecording) {
Toast.makeText(this, "Recorder stopped.",Toast.LENGTH_SHORT).show();
mRecorder.stop();
}
mRecorder.release();
mPlayer.stop();
mPlayer.release();
super.onDestroy();
}

The app should be ready to take for a spin. Since voice recording isn’t supported on the emulator, you’ll need to run the demo on an actual device. Operation is self-evident: say something and then play it back (Figure A).

Figure A

Pretty easy, right? And best of all, I’m sure it will provide you with hours of entertainment. I’ve already recorded an a capella rendition of Bon Jovi’s “Dead or Alive” for our next family outing to the grocery.

Automatically sign up for TechRepublic's App Builder newsletter!

Get IT Tips, news, and reviews delivered directly to your inbox by subscribing to TechRepublic’s free newsletters.

William J. Francis

About William J. Francis

William began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intelligence Corps.

William J. Francis

William J. Francis
William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intelligence Corps. Throughout his career William has published numerous technical articles, as well as the occasional short story.

William J. Francis

William J. Francis
William created the Who Moved My Cheese? game, which is available in the Android Market.