Upload
ngotuannghia1
View
241
Download
2
Embed Size (px)
Citation preview
8/2/2019 Android Building Audio Player Tutorial
1/33
Su tm v convert bi TVDT
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, 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 = newMediaPlayer();
// Set data source -setDataSource("/sdcard/path_to_song");
// Play audiomp.start();
// Pause audiomp.pause();
// Reset mediaplayermp.reset();
// Get song length duration - in millisecondsmp.getDuration();
// Get current duration - in millisecondsmp.getCurrentDuration();
// Move song to particular second - used for Forward or Backwardmp.seekTo(positon); // position in milliseconds
// Check if song is playing or notmp.isPlaying(); // returns true or false
8/2/2019 Android Building Audio Player Tutorial
2/33
Su tm v convert bi TVDT
1. 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)
8/2/2019 Android Building Audio Player Tutorial
3/33
Su tm v convert bi TVDT
2. 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.
8/2/2019 Android Building Audio Player Tutorial
4/33
Su tm v convert bi TVDT
3. 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.
btn_play.xml
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:
seekbar_progress_bg.xml
http://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/android8/2/2019 Android Building Audio Player Tutorial
5/33
Su tm v convert bi TVDT
Changing SeekBar Progress:
seekbar_progress.xml
Actual seekbar which uses above xml files:
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.
http://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/androidhttp://schemas.android.com/apk/res/android8/2/2019 Android Building Audio Player Tutorial
6/33
Su tm v convert bi TVDT
player.xml
8/2/2019 Android Building Audio Player Tutorial
7/33
Su tm v convert bi TVDT
android:id="@+id/player_footer_bg" android:layout_width="fill_parent" android:layout_height="100dp"android:layout_alignParentBottom="true" android:background="@layout/bg_player_footer" android:gravity="center">
8/2/2019 Android Building Audio Player Tutorial
8/33
Su tm v convert bi TVDT
android:id="@+id/songProgressBar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:layout_marginLeft="20dp" android:layout_marginBottom="20dp" android:layout_above="@id/player_footer_bg" android:thumb="@drawable/seek_handler" android:progressDrawable="@drawable/seekbar_progress" android:paddingLeft="6dp"android:paddingRight="6dp"/>
8/2/2019 Android Building Audio Player Tutorial
9/33
Su tm v convert bi TVDT
The 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 thisAndroid ListView
Tutorialand get an idea of listview layout.
http://www.androidhive.info/2011/10/android-listview-tutorial/http://www.androidhive.info/2011/10/android-listview-tutorial/http://www.androidhive.info/2011/10/android-listview-tutorial/http://www.androidhive.info/2011/10/android-listview-tutorial/http://www.androidhive.info/2011/10/android-listview-tutorial/http://www.androidhive.info/2011/10/android-listview-tutorial/8/2/2019 Android Building Audio Player Tutorial
10/33
Su tm v convert bi TVDT
Create an xml file under drawable folder and name it as list_selector.xml and type followingcode. This xml is used for gradient background for list item.
list_selector.xml
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.
playlist.xml
Also create a new xml file under layout folder for single List Item. Name fileasplaylist_item.xml and type following code. This xml file is for single list item which holds song
title.
playlist_item.xml
8/2/2019 Android Building Audio Player Tutorial
11/33
Su tm v convert bi TVDT
android:id="@+id/songTitle"android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="16dp"android:padding="10dp"android:color="#f3f3f3"/>
By using above layout we can achieve following list view by loading data into it.
7. Writing Class for reading MP3 files fromSDcard
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.
8/2/2019 Android Building Audio Player Tutorial
12/33
Su tm v convert bi TVDT
SongsManager.mp3packagecom.androidhive.musicplayer;
importjava.io.File;importjava.io.FilenameFilter;importjava.util.ArrayList;
importjava.util.HashMap;
publicclassSongsManager {// SDCard PathfinalString MEDIA_PATH = newString("/sdcard/");privateArrayList songsList = newArrayList();
// ConstructorpublicSongsManager(){
}
/*** Function to read all mp3 files from sdcard* and store the details in ArrayList* */publicArrayList getPlayList(){
File home = newFile(MEDIA_PATH);
if(home.listFiles(newFileExtensionFilter()).length > 0) {for(File file : home.listFiles(newFileExtensionFilter())) {
HashMap song = newHashMap();song.put("songTitle", file.getName().substring(0,
(file.getName().length() - 4)));song.put("songPath", file.getPath());
// Adding each song to SongListsongsList.add(song);
}}// return songs list arrayreturnsongsList;
}
/*** Class to filter files which are having .mp3 extension* */classFileExtensionFilter implementsFilenameFilter {
publicbooleanaccept(File dir, String name) {return(name.endsWith(".mp3") || name.endsWith(".MP3"));}
}}
8/2/2019 Android Building Audio Player Tutorial
13/33
Su tm v convert bi TVDT
8. 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.javapackagecom.androidhive.musicplayer;
importjava.util.ArrayList;importjava.util.HashMap;
importandroid.app.ListActivity;importandroid.content.Intent;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.AdapterView;importandroid.widget.AdapterView.OnItemClickListener;
importandroid.widget.ListAdapter;importandroid.widget.ListView;importandroid.widget.SimpleAdapter;
publicclassPlayListActivity extendsListActivity {// Songs listpublicArrayList songsList = newArrayList();
@OverridepublicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.playlist);
ArrayList songsListData = newArrayList();
SongsManager plm = newSongsManager();// get all songs from sdcardthis.songsList = plm.getPlayList();
// looping through playlistfor(inti = 0; i < songsList.size(); i++) {
// creating new HashMapHashMap song = songsList.get(i);
// adding HashList to ArrayListsongsListData.add(song);
}
// Adding menuItems to ListViewListAdapter adapter = newSimpleAdapter(this, songsListData,
R.layout.playlist_item, newString[] { "songTitle"}, newint[] {R.id.songTitle });
8/2/2019 Android Building Audio Player Tutorial
14/33
Su tm v convert bi TVDT
setListAdapter(adapter);
// selecting single ListView itemListView lv = getListView();// listening to single listitem clicklv.setOnItemClickListener(newOnItemClickListener() {
@OverridepublicvoidonItemClick(AdapterView parent, View view,
intposition, longid) {// getting listitem indexintsongIndex = position;
// Starting new intentIntent in = newIntent(getApplicationContext(),
AndroidBuildingMusicPlayerActivity.class); // Sending songIndex to PlayerActivityin.putExtra("songIndex", songIndex);setResult(100, in);
// Closing PlayListViewfinish();}
});}
}
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.javapackagecom.androidhive.musicplayer;
publicclassUtilities {
/*** Function to convert milliseconds time to* Timer Format* Hours:Minutes:Seconds* */publicString milliSecondsToTimer(longmilliseconds){
String finalTimerString = "";String secondsString = "";
// Convert total duration into timeinthours = (int)( milliseconds / (1000*60*60));intminutes = (int)(milliseconds % (1000*60*60)) / (1000*60);intseconds = (int) ((milliseconds % (1000*60*60)) % (1000*60)
8/2/2019 Android Building Audio Player Tutorial
15/33
Su tm v convert bi TVDT
/ 1000);// Add hours if thereif(hours > 0){
finalTimerString = hours + ":";}
// Prepending 0 to seconds if it is one digitif(seconds < 10){secondsString = "0"+ seconds;
}else{secondsString = ""+ seconds;}
finalTimerString = finalTimerString + minutes + ":"+secondsString;
// return timer stringreturnfinalTimerString;
}
/*** Function to get Progress percentage* @param currentDuration* @param totalDuration* */publicintgetProgressPercentage(longcurrentDuration, long
totalDuration){Double percentage = (double) 0;
longcurrentSeconds = (int) (currentDuration / 1000);longtotalSeconds = (int) (totalDuration / 1000);
// calculating percentage
percentage =(((double)currentSeconds)/totalSeconds)*100;
// return percentagereturnpercentage.intValue();
}
/*** Function to change progress to timer* @param progress -* @param totalDuration* returns current duration in milliseconds* */publicintprogressToTimer(intprogress, inttotalDuration) {
intcurrentDuration = 0;totalDuration = (int) (totalDuration / 1000);currentDuration = (int) ((((double)progress) / 100) *
totalDuration);
// return current duration in millisecondsreturncurrentDuration * 1000;
}}
8/2/2019 Android Building Audio Player Tutorial
16/33
Su tm v convert bi TVDT
7. 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.javapublicclassAndroidBuildingMusicPlayerActivity extendsActivity
implementsOnCompletionListener, SeekBar.OnSeekBarChangeListener {
Now declare all variable needed for this audio player class.
AndroidBuildingMusicPlayerActivity.javapublicclassAndroidBuildingMusicPlayerActivity extendsActivity
implementsOnCompletionListener, SeekBar.OnSeekBarChangeListener {
privateImageButton btnPlay;privateImageButton btnForward;privateImageButton btnBackward;privateImageButton btnNext;privateImageButton btnPrevious;privateImageButton btnPlaylist;privateImageButton btnRepeat;privateImageButton btnShuffle;privateSeekBar songProgressBar;privateTextView songTitleLabel;privateTextView songCurrentDurationLabel;
privateTextView songTotalDurationLabel;// Media Player
private MediaPlayer mp;// Handler to update UI timer, progress bar etc,.privateHandler mHandler = newHandler();;privateSongsManager songManager;privateUtilities utils;privateintseekForwardTime = 5000; // 5000 millisecondsprivateintseekBackwardTime = 5000; // 5000 millisecondsprivateintcurrentSongIndex = 0;privatebooleanisShuffle = false;privatebooleanisRepeat = false;privateArrayList songsList = newArrayList();
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);
8/2/2019 Android Building Audio Player Tutorial
17/33
Su tm v convert bi TVDT
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);
// Mediaplayermp = newMediaPlayer();songManager = newSongsManager();utils = newUtilities();
// ListenerssongProgressBar.setOnSeekBarChangeListener(this); // Importantmp.setOnCompletionListener(this); // Important
// Getting all songs listsongsList = songManager.getPlayList();
Launching PlayList
Write click event listener to playlist button. On clicking playlist button we need to
launchPlayListAcitivity.java and from listview on selecting a particular song we need
getsongIndex.
AndroidBuildingMusicPlayerActivity.java/**
* Button Click event for Play list click event* Launches list activity which displays list of songs* */btnPlaylist.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
Intent i = newIntent(getApplicationContext(),PlayListActivity.class);
startActivityForResult(i, 100);}
});
To receive the selected songIndex add following fucntion. (Make sure that you added this function
outside of onCreate method)
8/2/2019 Android Building Audio Player Tutorial
18/33
Su tm v convert bi TVDT
AndroidBuildingMusicPlayerActivity.java/**
* Receiving song index from playlist view* and play the song* */@Override
protectedvoidonActivityResult(intrequestCode,intresultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if(resultCode == 100){
currentSongIndex = data.getExtras().getInt("songIndex");// play selected songplaySong(currentSongIndex);
}
}
Playing Song
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* */
publicvoid playSong(intsongIndex){// Play songtry{
mp.reset();mp.setDataSource(songsList.get(songIndex).get("songPath")); mp.prepare();mp.start();// Displaying Song titleString songTitle = songsList.get(songIndex).get("songTitle");songTitleLabel.setText(songTitle);
// Changing Button Image to pause imagebtnPlay.setImageResource(R.drawable.btn_pause);
// set Progress bar valuessongProgressBar.setProgress(0); songProgressBar.setMax(100);
// Updating progress barupdateProgressBar();
} catch(IllegalArgumentException e) {e.printStackTrace();
} catch(IllegalStateException e) {
8/2/2019 Android Building Audio Player Tutorial
19/33
Su tm v convert bi TVDT
e.printStackTrace();} catch(IOException e) {
e.printStackTrace();}
}
Forward / 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() {
@OverridepublicvoidonClick(View arg0) {
// get current song positionintcurrentPosition = mp.getCurrentPosition();// check if seekForward time is lesser than song durationif(currentPosition + seekForwardTime
8/2/2019 Android Building Audio Player Tutorial
20/33
Su tm v convert bi TVDT
if(currentPosition - seekBackwardTime >= 0){// forward songmp.seekTo(currentPosition - seekBackwardTime);
}else{// backward to starting positionmp.seekTo(0);
}
}});
Next / 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() {
@OverridepublicvoidonClick(View arg0) {
// check if next song is there or not if(currentSongIndex < (songsList.size() - 1)){
playSong(currentSongIndex + 1);currentSongIndex = currentSongIndex + 1;
}else{// play first songplaySong(0);currentSongIndex = 0;
}
}});
Back button click event which plays previous song if presents or plays last song
AndroidBuildingMusicPlayerActivity.java/**
* Back button click event* Plays previous song by currentSongIndex - 1* */btnPrevious.setOnClickListener(new View.OnClickListener() {
@Override
8/2/2019 Android Building Audio Player Tutorial
21/33
Su tm v convert bi TVDT
publicvoidonClick(View arg0) {if(currentSongIndex > 0){
playSong(currentSongIndex - 1);currentSongIndex = currentSongIndex - 1;
}else{// play last songplaySong(songsList.size() - 1);currentSongIndex = songsList.size() - 1;
}
}});
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* */publicvoidupdateProgressBar() {
mHandler.postDelayed(mUpdateTimeTask, 100);}
/*** Background Runnable thread
* */privateRunnable mUpdateTimeTask = newRunnable() {
publicvoidrun() {longtotalDuration = mp.getDuration();longcurrentDuration = mp.getCurrentPosition();
// Displaying Total Duration timesongTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDura// Displaying time completed playingsongCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(current
// Updating progress barintprogress = (int)(utils.getProgressPercentage(currentDuration,
totalDuration));//Log.d("Progress", ""+progress);songProgressBar.setProgress(progress);
// Running this thread after 100 millisecondsmHandler.postDelayed(this, 100);
}};
http://developer.android.com/resources/articles/timed-ui-updates.htmlhttp://developer.android.com/resources/articles/timed-ui-updates.htmlhttp://developer.android.com/resources/articles/timed-ui-updates.htmlhttp://developer.android.com/resources/articles/timed-ui-updates.html8/2/2019 Android Building Audio Player Tutorial
22/33
Su tm v convert bi TVDT
/**** */@OverridepublicvoidonProgressChanged(SeekBar seekBar, intprogress, booleanfromTouch) {
}
/*** When user starts moving the progress handler* */@OverridepublicvoidonStartTrackingTouch(SeekBar seekBar) {
// remove message Handler from updating progress barmHandler.removeCallbacks(mUpdateTimeTask);
}
/*** When user stops moving the progress hanlder
* */@OverridepublicvoidonStopTrackingTouch(SeekBar seekBar) {
mHandler.removeCallbacks(mUpdateTimeTask); inttotalDuration = mp.getDuration();intcurrentPosition = utils.progressToTimer(seekBar.getProgress(), totalDura
// forward or backward to certain secondsmp.seekTo(currentPosition);
// update timer progress againupdateProgressBar();
}
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* */btnRepeat.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
if(isRepeat){isRepeat = false;Toast.makeText(getApplicationContext(), "Repeat is OFF",
8/2/2019 Android Building Audio Player Tutorial
23/33
Su tm v convert bi TVDT
Toast.LENGTH_SHORT).show();btnRepeat.setImageResource(R.drawable.btn_repeat);
}else{// make repeat to trueisRepeat = true;Toast.makeText(getApplicationContext(), "Repeat is ON",
Toast.LENGTH_SHORT).show();// make shuffle to falseisShuffle = false;btnRepeat.setImageResource(R.drawable.btn_repeat_focused); btnShuffle.setImageResource(R.drawable.btn_shuffle);
}}
});
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* */btnShuffle.setOnClickListener(new View.OnClickListener() {
@Override
publicvoidonClick(View arg0) {if(isShuffle){isShuffle = false;Toast.makeText(getApplicationContext(), "Shuffle is OFF",
Toast.LENGTH_SHORT).show();btnShuffle.setImageResource(R.drawable.btn_shuffle);
}else{// make repeat to trueisShuffle= true;Toast.makeText(getApplicationContext(), "Shuffle is ON",
Toast.LENGTH_SHORT).show();// make shuffle to falseisRepeat = false;btnShuffle.setImageResource(R.drawable.btn_shuffle_focused); btnRepeat.setImageResource(R.drawable.btn_repeat);
}}
});
Implementing song onCompletion Listener
8/2/2019 Android Building Audio Player Tutorial
24/33
Su tm v convert bi TVDT
It 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* */@OverridepublicvoidonCompletion(MediaPlayer arg0) {
// check for repeat is ON or OFFif(isRepeat){
// repeat is on play same song againplaySong(currentSongIndex);
} elseif(isShuffle){// shuffle is on - play a random songRandom rand = newRandom();currentSongIndex = rand.nextInt((songsList.size() - 1) - 0+
1) + 0;playSong(currentSongIndex);
} else{// no repeat or shuffle ON - play next songif(currentSongIndex < (songsList.size() - 1)){
playSong(currentSongIndex + 1);currentSongIndex = currentSongIndex + 1;
}else{// play first songplaySong(0);currentSongIndex = 0;
}
}}
Update your AndroidManifest.xml
Update your AndroidManifest.xml to following code.
Addandroid:configChanges=keyboardHidden|orientation to your main activity node.
AndroidManifest.xml
8/2/2019 Android Building Audio Player Tutorial
25/33
Su tm v convert bi TVDT
android:icon="@drawable/ic_launcher" android:label="@string/app_name" >
Final Code
Following is complete code for the AndroidBuildingMusicPlayerActivity.javaclass.
AndroidBuildingMusicPlayerActivity.javapackagecom.androidhive.musicplayer;
importjava.io.IOException;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.Random;
importandroid.app.Activity;importandroid.content.Intent;importandroid.media.MediaPlayer;importandroid.media.MediaPlayer.OnCompletionListener; importandroid.os.Bundle;importandroid.os.Handler;importandroid.view.View;importandroid.widget.ImageButton;
importandroid.widget.SeekBar;importandroid.widget.TextView;importandroid.widget.Toast;
publicclassAndroidBuildingMusicPlayerActivity extendsActivity implementsOnCompletiSeekBar.OnSeekBarChangeListener {
privateImageButton btnPlay;privateImageButton btnForward;
8/2/2019 Android Building Audio Player Tutorial
26/33
Su tm v convert bi TVDT
privateImageButton btnBackward;privateImageButton btnNext;privateImageButton btnPrevious;privateImageButton btnPlaylist;privateImageButton btnRepeat;privateImageButton btnShuffle;privateSeekBar songProgressBar;privateTextView songTitleLabel;privateTextView songCurrentDurationLabel;privateTextView songTotalDurationLabel;// Media Player
private MediaPlayer mp;// Handler to update UI timer, progress bar etc,.privateHandler mHandler = newHandler();;privateSongsManager songManager;privateUtilities utils;privateintseekForwardTime = 5000; // 5000 millisecondsprivateintseekBackwardTime = 5000; // 5000 millisecondsprivateintcurrentSongIndex = 0;privatebooleanisShuffle = false;
privatebooleanisRepeat = false;privateArrayList songsList = newArrayList
8/2/2019 Android Building Audio Player Tutorial
27/33
Su tm v convert bi TVDT
playSong(0);
/*** Play button click event* plays a song and changes button to pause image* pauses a song and changes button to play image
* */btnPlay.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
// check for already playingif(mp.isPlaying()){
if(mp!=null){mp.pause();// Changing button image to play buttonbtnPlay.setImageResource(R.drawable.btn_play);
}}else{
// Resume songif(mp!=null){
mp.start();// Changing button image to pause buttonbtnPlay.setImageResource(R.drawable.btn_pause);
}}
}});
/*** Forward button click event* Forwards song specified seconds* */btnForward.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
// get current song positionintcurrentPosition = mp.getCurrentPosition();// check if seekForward time is lesser than song durationif(currentPosition + seekForwardTime
8/2/2019 Android Building Audio Player Tutorial
28/33
Su tm v convert bi TVDT
btnBackward.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
// get current song positionintcurrentPosition = mp.getCurrentPosition();
// check if seekBackward time is greater than 0 secif(currentPosition - seekBackwardTime >= 0){// forward songmp.seekTo(currentPosition - seekBackwardTime);
}else{// backward to starting positionmp.seekTo(0);
}
}});
/**
* Next button click event* Plays next song by taking currentSongIndex + 1* */btnNext.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
// check if next song is there or not if(currentSongIndex < (songsList.size() - 1)){
playSong(currentSongIndex + 1);currentSongIndex = currentSongIndex + 1;
}else{// play first songplaySong(0);currentSongIndex = 0;
}
}});
/*** Back button click event* Plays previous song by currentSongIndex - 1* */btnPrevious.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
if(currentSongIndex > 0){playSong(currentSongIndex - 1);currentSongIndex = currentSongIndex - 1;
}else{// play last songplaySong(songsList.size() - 1);currentSongIndex = songsList.size() - 1;
}
8/2/2019 Android Building Audio Player Tutorial
29/33
Su tm v convert bi TVDT
}});
/*** Button Click event for Repeat button
* Enables repeat flag to true* */btnRepeat.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
if(isRepeat){isRepeat = false;Toast.makeText(getApplicationContext(), "Repeat is OFF", Toast.LbtnRepeat.setImageResource(R.drawable.btn_repeat);
}else{// make repeat to trueisRepeat = true;
Toast.makeText(getApplicationContext(), "Repeat is ON", Toast.LE// make shuffle to falseisShuffle = false;btnRepeat.setImageResource(R.drawable.btn_repeat_focused); btnShuffle.setImageResource(R.drawable.btn_shuffle);
}}
});
/*** Button Click event for Shuffle button* Enables shuffle flag to true* */btnShuffle.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
if(isShuffle){isShuffle = false;Toast.makeText(getApplicationContext(), "Shuffle is OFF", Toast.btnShuffle.setImageResource(R.drawable.btn_shuffle);
}else{// make repeat to trueisShuffle= true;Toast.makeText(getApplicationContext(), "Shuffle is ON", Toast.L// make shuffle to falseisRepeat = false;
btnShuffle.setImageResource(R.drawable.btn_shuffle_focused); btnRepeat.setImageResource(R.drawable.btn_repeat);
}}
});
/*** Button Click event for Play list click event* Launches list activity which displays list of songs
8/2/2019 Android Building Audio Player Tutorial
30/33
Su tm v convert bi TVDT
* */btnPlaylist.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View arg0) {
Intent i = newIntent(getApplicationContext(), PlayListActivity.clas
startActivityForResult(i, 100);}});
}
/*** Receiving song index from playlist view* and play the song* */@OverrideprotectedvoidonActivityResult(intrequestCode,
intresultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);if(resultCode == 100){currentSongIndex = data.getExtras().getInt("songIndex");// play selected songplaySong(currentSongIndex);
}
}
/*** Function to play a song* @param songIndex - index of song* */
publicvoid playSong(intsongIndex){// Play songtry{
mp.reset();mp.setDataSource(songsList.get(songIndex).get("songPath")); mp.prepare();mp.start();// Displaying Song titleString songTitle = songsList.get(songIndex).get("songTitle");songTitleLabel.setText(songTitle);
// Changing Button Image to pause imagebtnPlay.setImageResource(R.drawable.btn_pause);
// set Progress bar valuessongProgressBar.setProgress(0); songProgressBar.setMax(100);
// Updating progress barupdateProgressBar();
} catch(IllegalArgumentException e) {e.printStackTrace();
} catch(IllegalStateException e) {
8/2/2019 Android Building Audio Player Tutorial
31/33
Su tm v convert bi TVDT
e.printStackTrace();} catch(IOException e) {
e.printStackTrace();}
}
/*** Update timer on seekbar* */publicvoidupdateProgressBar() {
mHandler.postDelayed(mUpdateTimeTask, 100);}
/*** Background Runnable thread* */privateRunnable mUpdateTimeTask = newRunnable() {
publicvoidrun() {longtotalDuration = mp.getDuration();longcurrentDuration = mp.getCurrentPosition();
// Displaying Total Duration timesongTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDura// Displaying time completed playingsongCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(current
// Updating progress barintprogress = (int)(utils.getProgressPercentage(currentDuration, tot//Log.d("Progress", ""+progress);songProgressBar.setProgress(progress);
// Running this thread after 100 millisecondsmHandler.postDelayed(this, 100);
}};
/**** */@OverridepublicvoidonProgressChanged(SeekBar seekBar, intprogress, booleanfromTouch) {
}
/**
* When user starts moving the progress handler* */@OverridepublicvoidonStartTrackingTouch(SeekBar seekBar) {
// remove message Handler from updating progress barmHandler.removeCallbacks(mUpdateTimeTask);
}
/*** When user stops moving the progress hanlder
8/2/2019 Android Building Audio Player Tutorial
32/33
Su tm v convert bi TVDT
* */@OverridepublicvoidonStopTrackingTouch(SeekBar seekBar) {
mHandler.removeCallbacks(mUpdateTimeTask); inttotalDuration = mp.getDuration();intcurrentPosition = utils.progressToTimer(seekBar.getProgress(), totalDura
// forward or backward to certain secondsmp.seekTo(currentPosition);
// update timer progress againupdateProgressBar();
}
/*** On Song Playing completed* if repeat is ON play same song again* if shuffle is ON play random song* */
@OverridepublicvoidonCompletion(MediaPlayer arg0) {
// check for repeat is ON or OFFif(isRepeat){
// repeat is on play same song againplaySong(currentSongIndex);
} elseif(isShuffle){// shuffle is on - play a random songRandom rand = newRandom();currentSongIndex = rand.nextInt((songsList.size() - 1) - 0+ 1) + 0;playSong(currentSongIndex);
} else{// no repeat or shuffle ON - play next songif(currentSongIndex < (songsList.size() - 1)){
playSong(currentSongIndex + 1);currentSongIndex = currentSongIndex + 1;
}else{// play first songplaySong(0);currentSongIndex = 0;
}}
}
@OverridepublicvoidonDestroy(){
super.onDestroy();mp.release();
}
}
8/2/2019 Android Building Audio Player Tutorial
33/33
Sending files to Emulator SDCard (For Testing)
To test this app in your android emulator you need to load your emulator with some songs. You can
send files to emulator sdcard using adb tool which comes with Android SDK.
Navigate to your android SDK folder/platform-tools/ using command line. And
usingpush command you can send files to sdcard. (Start your emulator before performing push
command)
platform-tools> adb push "c:\Songs\White Flag.mp3" "/sdcard/"
Run your application.