Sei sulla pagina 1di 12

CreateaMusicPlayeronAndroid:Project

Setup
bySueSmith 12Mar2014
Difficulty: Beginner Length: Medium Languages: English

AndroidSDK

MobileDevelopment

TheAndroidplatformprovidesresourcesforhandlingmediaplayback,whichyourapps
canusetocreateaninterfacebetweentheuserandtheirmusicfiles.Inthistutorial
series,wewillcreateabasicmusicplayerapplicationforAndroid.Theappwillpresent
alistofsongsontheuserdevice,sothattheusercanselectsongstoplay.Theappwill
alsopresentcontrolsforinteractingwithplaybackandwillcontinueplayingwhenthe
usermovesawayfromtheapp,withanotificationdisplayedwhileplaybackelapses.

LookingforaQuickSolution?
Ifyou'relookingforaquicksolution,there'sagreatcollectionofAndroidapp
templatesoveratEnvatoMarket.
Inparticular,thisAndroidMusicPlayerapptemplateisagreatwaytogetstartedwith
buildingyourownapp."LiteMusic"isapremiumplayerapptemplateinAndroid,witha
cleaninterface,that'ssimpleandeleganttouse.

Introduction
Buildingthemusicplayerwillinvolveusingthe ContentResolver classtoretrievetracks
onthedevice,the MediaPlayer classtoplayaudioandthe MediaController classto
controlplayback.Wewillalsousea Service instancetoplayaudiowhentheuserisnot
directlyinteractingwiththeapp.Youshouldbeabletocompletethisseriesifyou'rean
intermediateAndroiddeveloper,soifyou'vealreadybuiltafewapps,thenthisseries
shouldn'tbeaproblemforyou.Hereisapreviewofthefinalapp:

Inthistutorial,wewillcreatetheappandquerytheuserdeviceforaudiofilesusing
the ContentResolver and Cursor classes.Inthenextpart,wewilluse
an Adapter instancetopresentthesongsinalistview,startingplaybackwhentheuser
tapsanitemfromthelist.Inthefinalinstallmentofthisseries,we'lluse
the MediaController classtogivetheusercontroloverplayback,implementfunctionsto
skipforwardandback,andincludeashufflefunction.Afterthisseries,wewillexplore
otheraspectsofmediaplaybackthatcanenhancetheapp,suchashandlingaudio
focus,presentingmediafilesindifferentways,andplayingstreamingmedia.

1.CreateandConfigureaNewProject

1.CreateandConfigureaNewProject
Step1
CreateanewAndroidproject.IfyouareusingEclipse,thenlettheIDE(Integrated
DevelopmentEnvironment)createamain Activity classandlayoutfileforyou.For
someofthecodeweuseintheseries,youwillneedaminimumAPIlevelof16,soyou
willneedtotakeadditionalstepstosupportolderversions.Onceyourprojectis
created,opentheproject'sManifestfile.Insidethe manifest element,addthefollowing
permission:
1

<usespermissionandroid:name="android.permission.WAKE_LOCK"

Wewillusethispermissiontoletmusicplaybackcontinuewhentheuser'sdevice
becomesidle.YourManifestshouldalreadycontainanelementforyour
main Activity class.Addthefollowingattributestothe activity elementtoset
the screenOrientation and launchMode :
1
2
3
4
5

<activity
android:name="com.example.musicplayer.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait">

Wewillsticktoportraitorientationforsimplicity.The launchMode willaidtheprocessof


navigatingbacktotheappaftermovingawayfromit.Wewilldisplayanotification
indicatingthesongcurrentlybeingplayed,tappingthenotificationwilltaketheuser
backtotheapp.Wearealsogoingtousea Service classformusicplayback.Addthe
followinglinetotheproject'sManifestinsidethe application elementandafter
the activity element:
1

<serviceandroid:name="com.example.musicplayer.MusicService"

Alterthepackagenametosuityourownandchangetheclassnameifyouwish.

Step2
Opentheproject'smainlayoutfileandreplaceitscontentswiththefollowinglayout:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#FF330000"
tools:context=".MainActivity">

<ListView
android:id="@+id/song_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</ListView>

</LinearLayout>

Makessuretoalterthetools:contextattributeifyourmain Activity classisnamed


differently.Thelayoutincludesa ListView inwhichwewillpresentthelistofsongs.
Wearegoingtoincludetwomenuitemsfortogglingtheshufflefunctionandforexiting
theapp.Openyourmainmenufile(res/menu/main.xml)andreplaceitscontentswith
thefollowing:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17

<menuxmlns:android="http://schemas.android.com/apk/res/android

<item
android:id="@+id/action_shuffle"
android:icon="@drawable/rand"
android:orderInCategory="1"
android:showAsAction="always"
android:title="Shuffle"/>

<item
android:id="@+id/action_end"
android:icon="@drawable/end"
android:orderInCategory="2"
android:showAsAction="always"
android:title="End"/>

</menu>

Ifyouprefer,youcanstorethetitlestringsintheres/values/strings.xmlfile.Thetwo
itemsrefertodrawablefiles.Createyourownorusethesetwoimagestostartwith:

Wewillalsouseanicontodisplayintheplaybacknotification.Createonenoworuse
theonebelow:

Thecodewillrefertotheimagesusingthenamesrand,end,andplaysomakesure
thatyouusethesamefilenames.Copytheimagestoyourproject'sdrawables
folder(s).Wewillimplementtheactionslater.

2.QuerytheDeviceforSongs
Step1
Let'squerytheuser'sdeviceforaudiofiles.First,addanewclasstoyourproject,
namingit Song .Wewillusethisclasstomodelthedataforasingleaudiofile.Insidethe
classdeclaration,addthreeinstancevariablesforthedatawewanttostoreforeach
track:
1
2
3

privatelongid;
privateStringtitle;
privateStringartist;

Next,addaconstructormethodinwhichweinstantiatetheinstancevariables:
1
2
3
4
5

publicSong(longsongID,StringsongTitle,StringsongArtist){
id=songID;
title=songTitle;
artist=songArtist;
}

Finally,addgetmethodsfortheinstancevariables:
1
2
3

publiclonggetID(){returnid;}
publicStringgetTitle(){returntitle;}
publicStringgetArtist(){returnartist;}

Ifyouplantousemoretrackinformation,thenyouarefreetoaddadditionalinstance
variablestotheclass.

Step2
Openthemain Activity classandaddthefollowingimports:
1
2
3
4
5
6
7

importjava.util.ArrayList;
importjava.util.Collections;
importjava.util.Comparator;
importandroid.net.Uri;
importandroid.content.ContentResolver;
importandroid.database.Cursor;
importandroid.widget.ListView;

Declarethefollowinginstancevariablesbeforethe onCreate method:


1
2

privateArrayList<Song>songList;
privateListViewsongView;

Wewillstorethesongsinalistanddisplaytheminthe ListView instanceinthemain


layout.In onCreate ,aftersettingthecontentview,retrievethe ListView instanceusing
theIDwegaveitinthemainlayout:
1

songView=(ListView)findViewById(R.id.song_list);

Instantiatethelistasshownbelow:
1

songList=newArrayList<Song>();

Next,inthemain Activity classdeclaration,aftertheexistingmethods,createahelper


methodtoretrievetheaudiofileinformation:
1
2
3

publicvoidgetSongList(){
//retrievesonginfo
}

Insidethismethod,createa ContentResolver instance,retrievetheURIforexternal


musicfiles,andcreatea Cursor instanceusingthe ContentResolver instancetoquery
themusicfiles:
1
2
3

ContentResolvermusicResolver=getContentResolver();
UrimusicUri=android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
CursormusicCursor=musicResolver.query(musicUri,null,null

Nowwecaniterateovertheresults,firstcheckingthatwehavevaliddata:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17

if(musicCursor!=null&&musicCursor.moveToFirst()){
//getcolumns
inttitleColumn=musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
intidColumn=musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
intartistColumn=musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
//addsongstolist
do{
longthisId=musicCursor.getLong(idColumn);
StringthisTitle=musicCursor.getString(titleColumn);
StringthisArtist=musicCursor.getString(artistColumn);
songList.add(newSong(thisId,thisTitle,thisArtist));
}
while(musicCursor.moveToNext());
}

Wefirstretrievethecolumnindexesforthedataitemsthatweareinterestedinforeach
song,thenweusethesetocreateanew Song objectandaddittothelist,before
continuingtoloopthroughtheresults.
Backin onCreate ,afterthecodeweadded,callthisnewmethod:
1

getSongList();

3.DisplaytheSongs
Step1
Nowwecandisplaythelistofsongsintheuserinterface.Inthe onCreate method,after
callingthehelpermethodwecreatedamomentago,let'ssortthedatasothatthe
songsarepresentedalphabetically:
1
2
3
4
5

Collections.sort(songList,newComparator<Song>(){
publicintcompare(Songa,Songb){
returna.getTitle().compareTo(b.getTitle());
}
});

Weusethe title variableinthe Song class,usingthegetmethodsweadded,to


implementa compare method,sortingthesongsbytitle.

Step2
Let'sdefinealayouttorepresenteachsonginthelist.Addanewfiletoyour
project'sres/layoutfolder,namingitsong.xmlandenteringthefollowing:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="songPicked"
android:orientation="vertical"
android:padding="5dp">

<TextView
android:id="@+id/song_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF99"
android:textSize="20sp"
android:textStyle="bold"/>

<TextView
android:id="@+id/song_artist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF99"
android:textSize="18sp"/>

</LinearLayout>

Feelfreetoamendthelayouttosuityourpreferences.Eachsonginthelistwillbe
representedbytitleandartisttextstrings,sowewillusethe TextViews todisplaythis
data.Noticethatthe LinearLayout openingtaglistsan onClick attribute.Wewillusethis
methodinthemain Activity classtorespondtousertapsonthesongsinthelist,
playingthesongrepresentedbythelistitemthatwastapped.

Step3
Wewillusean Adapter tomapthesongstothelistview.Addanewclasstoyourapp,
namingitSongAdapteroranothernameofyourchoice.Whencreatingtheclass,give
itthesuperclass android.widget.BaseAdapter .Eclipseshouldinsertthefollowingoutline:
01
02
03
04
05
06
07
08

publicclassSongAdapterextendsBaseAdapter{

@Override
publicintgetCount(){
//TODOAutogeneratedmethodstub
return0;
}

@Override

09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

@Override
publicObjectgetItem(intarg0){
//TODOAutogeneratedmethodstub
returnnull;
}

@Override
publiclonggetItemId(intarg0){
//TODOAutogeneratedmethodstub
return0;
}

@Override
publicViewgetView(intarg0,Viewarg1,ViewGrouparg2){
//TODOAutogeneratedmethodstub
returnnull;
}

You'llneedtoaddthefollowingimports:
1
2
3
4
5

importjava.util.ArrayList;
importandroid.content.Context;
importandroid.view.LayoutInflater;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;

Insidetheclassdeclaration,declarethefollowinginstancevariables:
1
2

privateArrayList<Song>songs;
privateLayoutInflatersongInf;

We'llpassthesonglistfromthemain Activity classandusethe LayoutInflater to


mapthetitleandartiststringstothe TextViews inthesonglayoutwecreated.
Aftertheinstancevariables,givetheadapteraconstructormethodtoinstantiatethem:
1
2
3
4

publicSongAdapter(Contextc,ArrayList<Song>theSongs){
songs=theSongs;
songInf=LayoutInflater.from(c);
}

Alterthecontentofthe getCount methodtoreturnthesizeofthelist:


1
2
3

@Override
publicintgetCount(){
returnsongs.size();
}

Youcanleavethe getItem and getItemId methodsuntouched.Updatethe


implementationofthe getView methodasshownbelow:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17

@Override
publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
//maptosonglayout
LinearLayoutsongLay=(LinearLayout)songInf.inflate
(R.layout.song,parent,false);
//gettitleandartistviews
TextViewsongView=(TextView)songLay.findViewById(R.id.song_title);
TextViewartistView=(TextView)songLay.findViewById(R.id.song_artist);
//getsongusingposition
SongcurrSong=songs.get(position);
//gettitleandartiststrings
songView.setText(currSong.getTitle());
artistView.setText(currSong.getArtist());
//setpositionastag
songLay.setTag(position);
returnsongLay;
}

Wesetthetitleandartisttextbyretrievingthecorrect Song instancefromthelistusing


thepositionindex,mappingthesestringstotheviewsweaddedtothesonglayoutfile.
Wealsosetthepositionastheviewtag,whichwillletusplaythecorrectsongwhenthe
userclicksaniteminthelist.Rememberthatthesong.xmllayoutfileincluded
an onClick attribute.Wewillusethemethodlistedtheretoretrievethetagin
the Activity .

Step3
Backinthemain Activity class,inthe onCreate methodaftersortingthelist,createa
newinstanceofthe Adapter classandsetitonthe ListView :
1
2

SongAdaptersongAdt=newSongAdapter(this,songList);
songView.setAdapter(songAdt);

Whenyouruntheapp,itshouldpresentthelistofsongsonthedevice,clickingthem
willcausetheapptothrowanexceptionatthemoment,butwewillimplementtheclick
handlerinthenexttutorial.

Conclusion

We'venowsettheappuptoreadsongsfromtheuserdevice.Inthenextpart,wewill
beginplaybackwhentheuserselectsasongusingthe MediaPlayer class.Wewill
implementplaybackusinga Service classsothatitwillcontinueastheuserinteracts
withotherapps.Finally,wewillusea MediaController classtogivetheusercontrolover
playback.
Ifyou'reeverinneedofextrahelpwithyourAndroidappdevelopmentprojects,youcan
findexperiencedAndroiddevelopersonEnvatoStudiotohelpyouwitheverything
fromUIdesigntocreatinganativeAndroidapp.

Potrebbero piacerti anche