Android Building Audio Player Tutorial In this tutorial i am going to discuss building a simple audio player with basic controls like play, pause, forward, backward, next, previous, play
Trang 1Android Building Audio Player Tutorial
In this tutorial i am going to discuss building a simple audio player with basic controls like play, pause, forward, backward, next, previous, playlist and seekbar This app basically will read all audio files(.mp3) from sdcard and plays selected song For this tutorial i am referencing MediaPlayer and
go through it if you need any documentation about usage
Android MediaPlayer Class
Android SDK is providing MediaPlayer Class to access android in built mediaplayer services like playing audio, video etc., In this tutorial i am using following functions of this class to control audio player
MediaPlayer mp = new MediaPlayer();
// Move song to particular second - used for Forward or Backward
mp.seekTo(positon); // position in milliseconds
// Check if song is playing or not
mp.isPlaying(); // returns true or false
Trang 21 Designing the Audio Player Layout
Design your audio player using some graphic designing softwares like photoshop I used photoshop
to design this app layout If you are not aware of designing just download the required images from the internet Following is a screenshot of the audio player which we are going to build in this tutorial (You can find this layout PSD in the download code)
Trang 32 Preparing Required Icons and Images
Once you are done with your app layout design, prepare the required icons and background images for the audio player application Prepare your icons in different states like default, focused and
pressed and place them all in your drawable folder
Trang 43 Writing XML layouts for ICON states
(default/hover/pressed)
After saving all the icons with different states, we need to write xml drawable for each icon Following
is a sample for play button Save this file under drawable folder
Note: You need to write xml drawable for each icon you used for the player
(likebtn_pause.xml, btn_next.xml etc,.)
4 Writing XML design for SeekBar
In this tutorial i used customized SeekBar to show song progress You can design the style of default SeekBar using xml styles In your drawable folder create to xml files and type the following code Changing SeekBar background:
Trang 5Changing SeekBar Progress:
5 Writing XML for Player Layout
So far we created separate xml layout for all the icons, seekbar Now we need to combine
everything into single layout Create a new file called player.xml under layout folder and paste the
following code
Trang 7<! Backward Button >
<ImageButton
android:id="@+id/btnBackward"
android:src="@drawable/btn_backward" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null"/>
<! Forward Button >
<ImageButton
android:id="@+id/btnForward"
android:src="@drawable/btn_forward" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null"/>
Trang 9The above xml will give following output layout
6 Writing XML for PlayList ListView
Playlist is displayed using a listview If you are not aware of listview go through this Android ListView Tutorial and get an idea of listview layout
Trang 10⇒ Create an xml file under drawable folder and name it as list_selector.xml and type following
code This xml is used for gradient background for list item
list_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<! Selector style for listrow >
⇒ Create a new xml file under layout layout folder and name it as playlist.xml and type the
following code This xml file is for listview
Trang 11By using above layout we can achieve following list view by loading data into it
7 Writing Class for reading MP3 files from
SDcard
So far we are done with static layouts for the player Now the actual code starts
Create a new class file and name it as SongsManager.java This class will read all the files from device sdcard and filters the files which are having mp3 extension
Trang 12SongsManager.mp3 package com.androidhive.musicplayer;
finalString MEDIA_PATH = newString("/sdcard/");
privateArrayList<HashMap<String, String>> songsList = newArrayList<HashMap<String, String>>();
* Function to read all mp3 files from sdcard
* and store the details in ArrayList
* */
public ArrayList<HashMap<String, String>> getPlayList(){
File home = newFile(MEDIA_PATH);
if (home.listFiles(new FileExtensionFilter()).length > 0) {
for (File file : home.listFiles(new FileExtensionFilter())) {
HashMap<String, String> song = new HashMap<String, String>();
class FileExtensionFilter implements FilenameFilter {
publicbooleanaccept(File dir, String name) {
return (name.endsWith(".mp3") || name.endsWith(".MP3"));
}
}
}
Trang 138 Writing Class for PlayList ListView
Create a new Activity class for playlist listview Name the file as PlayListActivity.java This class will
display list of songs in list layout by using SongsManager.java class
PlayListActivity.java package com.androidhive.musicplayer;
SongsManager plm = new SongsManager();
// get all songs from sdcard
this.songsList = plm.getPlayList();
// looping through playlist
for (int i = 0; i < songsList.size(); i++) {
// creating new HashMap
HashMap<String, String> song = songsList.get(i);
// Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(this, songsListData,
R.layout.playlist_item, new String[] { "songTitle" }, new int[] {
R.id.songTitle });
Trang 14
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting listitem index
int songIndex = position;
// Starting new intent
Intent in = new Intent(getApplicationContext(),
9 Helper Class functions
Create a new class called Utilities.java for handling extra work like converting time to progress
percentage and vice-versa Also it has function to convert millisecond to a timer string which will
displayed on the seekbar of the player
Utilities.java package com.androidhive.musicplayer;
// Convert total duration into time
int hours = (int)( milliseconds / (1000*60*60));
int minutes = (int)(milliseconds % (1000*60*60)) / (1000*60);
int seconds = (int) ((milliseconds % (1000*60*60)) % (1000*60)
Trang 15totalDuration = (int) (totalDuration / 1000);
currentDuration = (int) ((((double)progress) / 100) * totalDuration);
Trang 167 Writing Classes needed for Audio Player
Open your main activity class which deals with main player interface and make the
classimplements from OnCompletionListener, SeekBar.OnSeekBarChangeListener
In this case my main activity name is AndroidBuildingMusicPlayerActivity
AndroidBuildingMusicPlayerActivity.java public class AndroidBuildingMusicPlayerActivity extends Activity
implements OnCompletionListener, SeekBar.OnSeekBarChangeListener {
Now declare all variable needed for this audio player class
AndroidBuildingMusicPlayerActivity.java public class AndroidBuildingMusicPlayerActivity extends Activity
implements OnCompletionListener, SeekBar.OnSeekBarChangeListener {
private ImageButton btnPlay;
private ImageButton btnForward;
private ImageButton btnBackward;
private ImageButton btnNext;
private ImageButton btnPrevious;
private ImageButton btnPlaylist;
private ImageButton btnRepeat;
private ImageButton btnShuffle;
private SeekBar songProgressBar;
privateTextView songTitleLabel;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
// Media Player
private MediaPlayer mp;
// Handler to update UI timer, progress bar etc,
private Handler mHandler = new Handler();;
private SongsManager songManager;
private Utilities utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
private int currentSongIndex = 0;
private boolean isShuffle = false;
private boolean isRepeat = false;
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
Now reference all buttons, images from xml layout to class
AndroidBuildingMusicPlayerActivity.java // All player buttons
btnPlay = (ImageButton) findViewById(R.id.btnPlay);
btnForward = (ImageButton) findViewById(R.id.btnForward);
btnBackward = (ImageButton) findViewById(R.id.btnBackward);
Trang 17btnNext = (ImageButton) findViewById(R.id.btnNext);
btnPrevious = (ImageButton) findViewById(R.id.btnPrevious);
btnPlaylist = (ImageButton) findViewById(R.id.btnPlaylist);
btnRepeat = (ImageButton) findViewById(R.id.btnRepeat);
btnShuffle = (ImageButton) findViewById(R.id.btnShuffle);
songProgressBar = (SeekBar) findViewById(R.id.songProgressBar);
songTitleLabel = (TextView) findViewById(R.id.songTitle);
songManager = new SongsManager();
utils = new Utilities();
AndroidBuildingMusicPlayerActivity.java /**
* Button Click event for Play list click event
* Launches list activity which displays list of songs
* */
btnPlaylist.setOnClickListener(new View.OnClickListener() {
@Override
publicvoidonClick(View arg0) {
Intent i = new Intent(getApplicationContext(),
Trang 18AndroidBuildingMusicPlayerActivity.java /**
* Receiving song index from playlist view
* and play the song
* */
@Override
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Add the following function to your class This function accepts songIndex as param and plays it
Also when start playing a song it switches the play button to pause button state
AndroidBuildingMusicPlayerActivity.java /**
* Function to play a song
* @param songIndex - index of song
// Displaying Song title
String songTitle = songsList.get(songIndex).get("songTitle"); songTitleLabel.setText(songTitle);
Trang 19Forward / Backward button click events
Add event listeners to Forward and Backward buttons which forwards or backwards song by specified seconds
Forward button click event – moves song to specified number of seconds forward
AndroidBuildingMusicPlayerActivity.java /**
* Forward button click event
* Forwards song specified seconds
* */
btnForward.setOnClickListener(new View.OnClickListener() {
@Override
publicvoidonClick(View arg0) {
// get current song position
int currentPosition = mp.getCurrentPosition();
// check if seekForward time is lesser than song duration if(currentPosition + seekForwardTime <=
* Backward button click event
* Backward song to specified seconds
* */
btnBackward.setOnClickListener(newView.OnClickListener() {
@Override
public void onClick(View arg0) {
// get current song position
int currentPosition = mp.getCurrentPosition();
// check if seekBackward time is greater than 0 sec
Trang 20Next / Back button click events
Add click listeners to next and back buttons
Next button click event – which plays next song from the playlist if presents else plays first song
AndroidBuildingMusicPlayerActivity.java /**
* Next button click event
* Plays next song by taking currentSongIndex + 1
* */
btnNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// check if next song is there or not
* Back button click event
* Plays previous song by currentSongIndex - 1
* */
btnPrevious.setOnClickListener(newView.OnClickListener() {
@Override
Trang 21public void onClick(View arg0) {
Updating SeekBar progress and Timer
To update progress bar timer i implemented a background thread which runs in background using a
Handler If you new to Handler follow this doc Updating the UI from a Timer
AndroidBuildingMusicPlayerActivity.java /**
* Update timer on seekbar
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
longtotalDuration = mp.getDuration();
long currentDuration = mp.getCurrentPosition();
// Displaying Total Duration time
songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration)); // Displaying time completed playing
songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration));
// Updating progress bar
int progress = (int)(utils.getProgressPercentage(currentDuration,
Trang 22public void onStartTrackingTouch(SeekBar seekBar) {
// remove message Handler from updating progress bar
inttotalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);
// forward or backward to certain seconds
Repeat button click event
On clicking repeat button we need to set isRepeat to true and vice-versa Also we need to change
image source of repeat button to focused state
AndroidBuildingMusicPlayerActivity.java /**
* Button Click event for Repeat button
* Enables repeat flag to true
Trang 23}
}
});
Shuffle button click event
On clicking shuffle button we need to set isShuffle to true and vice-versa Also we need to change
image source of shuffle button to focused state
AndroidBuildingMusicPlayerActivity.java /**
* Button Click event for Shuffle button
* Enables shuffle flag to true
Trang 24It is important to implement this listener which will notify you once the song is completed playing In
this method we need to play next song automatically depending on repeat andshuffle conditions
AndroidBuildingMusicPlayerActivity.java /**
* On Song Playing completed
* if repeat is ON play same song again
* if shuffle is ON play random song
// shuffle is on - play a random song
Random rand = new Random();
Update your AndroidManifest.xml
Addandroid:configChanges=”keyboardHidden|orientation” to your main activity node
Trang 25private ImageButton btnPlay;
privateImageButton btnForward;
Trang 26private ImageButton btnBackward;
private ImageButton btnNext;
privateImageButton btnPrevious;
private ImageButton btnPlaylist;
privateImageButton btnRepeat;
private ImageButton btnShuffle;
private SeekBar songProgressBar;
private TextView songTitleLabel;
private TextView songCurrentDurationLabel;
privateTextView songTotalDurationLabel;
// Media Player
private MediaPlayer mp;
// Handler to update UI timer, progress bar etc,
private Handler mHandler = new Handler();;
private SongsManager songManager;
private Utilities utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
private int currentSongIndex = 0;
private boolean isShuffle = false;
private boolean isRepeat = false;
privateArrayList<HashMap<String, String>> songsList = newArrayList<HashMap<String, String>>();
// All player buttons
btnPlay = (ImageButton) findViewById(R.id.btnPlay);
btnForward = (ImageButton) findViewById(R.id.btnForward);
btnBackward = (ImageButton) findViewById(R.id.btnBackward);
btnNext = (ImageButton) findViewById(R.id.btnNext);
btnPrevious = (ImageButton) findViewById(R.id.btnPrevious);
btnPlaylist = (ImageButton) findViewById(R.id.btnPlaylist);
btnRepeat = (ImageButton) findViewById(R.id.btnRepeat);
btnShuffle = (ImageButton) findViewById(R.id.btnShuffle);
songProgressBar = (SeekBar) findViewById(R.id.songProgressBar);
songTitleLabel = (TextView) findViewById(R.id.songTitle);
songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel);
songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel);
// Mediaplayer
mp = new MediaPlayer();
songManager = new SongsManager();
utils = new Utilities();