11.更新AndroidManifest.xml文件
添加android:configChanges=”keyboardHidden|orientation”,
AndroidManifest.xml
<?xml version="1.0"encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidhive.musicplayer"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<activity
android:name=".AndroidBuildingMusicPlayerActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".PlayListActivity"/>
</application>
</manifest>
<!-- AndroidBuildingMusicPlayerActivity -->
12.最后的代码
下面是AndroidBuildingMusicPlayerActivity类的完整代码
packagecom.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; publicclassAndroidBuildingMusicPlayerActivityextendsActivityimplementsOnCompletionListener, 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 milliseconds privateintseekBackwardTime =5000;// 5000 milliseconds privateintcurrentSongIndex =0; privatebooleanisShuffle =false; privatebooleanisRepeat =false; privateArrayList<HashMap<String, String>> songsList = newArrayList<HashMap<String, String>>(); @Override publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.player); // 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 =newMediaPlayer(); songManager =newSongsManager(); utils =newUtilities(); // Listeners songProgressBar.setOnSeekBarChangeListener(this);// Important mp.setOnCompletionListener(this);// Important // Getting all songs list songsList = songManager.getPlayList(); // By default play first song 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(newView.OnClickListener() { @Override publicvoidonClick(View arg0) { // check for already playing if(mp.isPlaying()){ if(mp!=null){ mp.pause(); // Changing button image to play button btnPlay.setImageResource(R.drawable.btn_play); } }else{ // Resume song if(mp!=null){ mp.start(); // Changing button image to pause button btnPlay.setImageResource(R.drawable.btn_pause); } } } }); /** * Forward button click event * Forwards song specified seconds * */ btnForward.setOnClickListener(newView.OnClickListener() { @Override publicvoidonClick(View arg0) { // get current song position intcurrentPosition = mp.getCurrentPosition(); // check if seekForward time is lesser than song duration if(currentPosition + seekForwardTime <= mp.getDuration()){ // forward song mp.seekTo(currentPosition + seekForwardTime); }else{ // forward to end position mp.seekTo(mp.getDuration()); } } }); /** * Backward button click event * Backward song to specified seconds * */ btnBackward.setOnClickListener(newView.OnClickListener() { @Override publicvoidonClick(View arg0) { // get current song position intcurrentPosition = mp.getCurrentPosition(); // check if seekBackward time is greater than 0 sec if(currentPosition - seekBackwardTime >= 0){ // forward song mp.seekTo(currentPosition - seekBackwardTime); }else{ // backward to starting position mp.seekTo(0); } } }); /** * Next button click event * Plays next song by taking currentSongIndex + 1 * */ btnNext.setOnClickListener(newView.OnClickListener() { @Override publicvoidonClick(View arg0) { // check if next song is there or not if(currentSongIndex < (songsList.size() - 1)){ playSong(currentSongIndex +1); currentSongIndex = currentSongIndex +1; }else{ // play first song playSong(0); currentSongIndex =0; } } }); /** * Back button click event * Plays previous song by currentSongIndex - 1 * */ btnPrevious.setOnClickListener(newView.OnClickListener() { @Override publicvoidonClick(View arg0) { if(currentSongIndex > 0){ playSong(currentSongIndex -1); currentSongIndex = currentSongIndex -1; }else{ // play last song playSong(songsList.size() -1); currentSongIndex = songsList.size() -1; } } }); /** * Button Click event for Repeat button * Enables repeat flag to true * */ btnRepeat.setOnClickListener(newView.OnClickListener() { @Override publicvoidonClick(View arg0) { if(isRepeat){ isRepeat =false; Toast.makeText(getApplicationContext(),"Repeat is OFF", Toast.LENGTH_SHORT).show(); btnRepeat.setImageResource(R.drawable.btn_repeat); }else{ // make repeat to true isRepeat =true; Toast.makeText(getApplicationContext(),"Repeat is ON", Toast.LENGTH_SHORT).show(); // make shuffle to false isShuffle =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(newView.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 true isShuffle=true; Toast.makeText(getApplicationContext(),"Shuffle is ON", Toast.LENGTH_SHORT).show(); // make shuffle to false isRepeat =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 * */ btnPlaylist.setOnClickListener(newView.OnClickListener() { @Override publicvoidonClick(View arg0) { Intent i =newIntent(getApplicationContext(), PlayListActivity.class); startActivityForResult(i,100); } }); } /** * 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 song playSong(currentSongIndex); } } /** * Function to play a song * @param songIndex - index of song * */ publicvoid playSong(intsongIndex){ // Play song try{ mp.reset(); mp.setDataSource(songsList.get(songIndex).get("songPath")); mp.prepare(); mp.start(); // Displaying Song title String songTitle = songsList.get(songIndex).get("songTitle"); songTitleLabel.setText(songTitle); // Changing Button Image to pause image btnPlay.setImageResource(R.drawable.btn_pause); // set Progress bar values songProgressBar.setProgress(0); songProgressBar.setMax(100); // Updating progress bar updateProgressBar(); }catch(IllegalArgumentException e) { e.printStackTrace(); }catch(IllegalStateException e) { 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 time songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration)); // Displaying time completed playing songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration)); // Updating progress bar intprogress = (int)(utils.getProgressPercentage(currentDuration, totalDuration)); //Log.d("Progress", ""+progress); songProgressBar.setProgress(progress); // Running this thread after 100 milliseconds mHandler.postDelayed(this,100); } }; /** * * */ @Override publicvoidonProgressChanged(SeekBar seekBar,intprogress,booleanfromTouch) { } /** * When user starts moving the progress handler * */ @Override publicvoidonStartTrackingTouch(SeekBar seekBar) { // remove message Handler from updating progress bar mHandler.removeCallbacks(mUpdateTimeTask); } /** * When user stops moving the progress hanlder * */ @Override publicvoidonStopTrackingTouch(SeekBar seekBar) { mHandler.removeCallbacks(mUpdateTimeTask); inttotalDuration = mp.getDuration(); intcurrentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration); // forward or backward to certain seconds mp.seekTo(currentPosition); // update timer progress again updateProgressBar(); } /** * On Song Playing completed * if repeat is ON play same song again * if shuffle is ON play random song * */ @Override publicvoidonCompletion(MediaPlayer arg0) { // check for repeat is ON or OFF if(isRepeat){ // repeat is on play same song again playSong(currentSongIndex); }elseif(isShuffle){ // shuffle is on - play a random song Random rand =newRandom(); currentSongIndex = rand.nextInt((songsList.size() -1) -0+1) +0; playSong(currentSongIndex); }else{ // no repeat or shuffle ON - play next song if(currentSongIndex < (songsList.size() - 1)){ playSong(currentSongIndex +1); currentSongIndex = currentSongIndex +1; }else{ // play first song playSong(0); currentSongIndex =0; } } } @Override publicvoidonDestroy(){ super.onDestroy(); mp.release(); } } |
14.往模拟器SDCard里添加mp3文件(用于测试)
最后,我们需要往模拟器里面添加几首歌曲用来播放。
1.在用你的Android模拟器来测试这个程序,你需要加载一些歌曲到你的模拟器。您可以使用adb工具,它往Android SDK模拟器SD卡发送文件。
导航到你的Android SDK文件夹/平台工具/使用命令行。和使用push命令,您可以发送文件到SD卡。 (开始你的模拟器执行推送命令之前)
导航到你的Android SDK文件夹/平台工具/使用命令行。和使用push命令,您可以发送文件到SD卡。 (开始你的模拟器执行推送命令之前)
platform-tools> adb push "c:\Songs\White Flag.mp3" "/sdcard/" |
15.运行
运行我们的程序,效果如下: