製作一個簡單的Android版的音樂播放器

音樂播放器是一個非常常見的應用,這篇博客就是介紹如何製作一個簡單的音樂播放器,這款音樂播放器具有以下的功能:播放歌曲、暫停播放歌曲、、顯示歌曲的總時長、顯示歌曲的當前播放時長、調節滑塊可以將歌曲調節到任何時間播放、退出音樂播放器

實現效果如下



實現方式:

第一步:使用Android Studio創建一個Android工程,並且修改activity_main.xml文件

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     tools:context="com.fyt.musicplayer.MainActivity"  
  7.     android:orientation="vertical">  
  8.   
  9.     <!--顯示播放進度-->  
  10.     <SeekBar  
  11.         android:id="@+id/sb"  
  12.         android:layout_width="match_parent"  
  13.         android:layout_height="wrap_content" />  
  14.   
  15.     <RelativeLayout  
  16.         android:layout_width="match_parent"  
  17.         android:layout_height="wrap_content">  
  18.   
  19.         <!--顯示當前進度-->  
  20.         <TextView  
  21.             android:id="@+id/tv_progress"  
  22.             android:layout_width="wrap_content"  
  23.             android:layout_height="wrap_content"  
  24.             android:text="00:00"/>  
  25.   
  26.         <!--顯示總進度-->  
  27.         <TextView  
  28.             android:id="@+id/tv_total"  
  29.             android:layout_width="wrap_content"  
  30.             android:layout_height="wrap_content"  
  31.             android:layout_alignParentRight="true"  
  32.             android:text="00:00"/>  
  33.   
  34.     </RelativeLayout>  
  35.   
  36.     <Button  
  37.         android:layout_width="wrap_content"  
  38.         android:layout_height="wrap_content"  
  39.         android:text="播放音樂"  
  40.         android:onClick="play"/>  
  41.   
  42.     <Button  
  43.         android:layout_width="wrap_content"  
  44.         android:layout_height="wrap_content"  
  45.         android:text="暫停播放"  
  46.         android:onClick="pausePlay"/>  
  47.   
  48.     <Button  
  49.         android:layout_width="wrap_content"  
  50.         android:layout_height="wrap_content"  
  51.         android:text="繼續播放"  
  52.         android:onClick="continuePlay"/>  
  53.   
  54.     <Button  
  55.         android:layout_width="wrap_content"  
  56.         android:layout_height="wrap_content"  
  57.         android:text="退出"  
  58.         android:onClick="exit"/>  
  59.   
  60. </LinearLayout>  


第二步:新建一個MusicService.java文件,用於處理音樂播放的邏輯

[java] view plain copy
  1. package com.fyt.musicplayer;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.media.MediaPlayer;  
  6. import android.os.Binder;  
  7. import android.os.Bundle;  
  8. import android.os.IBinder;  
  9. import android.os.Message;  
  10. import android.support.annotation.Nullable;  
  11.   
  12. import java.io.IOException;  
  13. import java.util.Timer;  
  14. import java.util.TimerTask;  
  15.   
  16. //創建一個繼承自服務的音樂服務類  
  17. public class MusicService extends Service {  
  18.   
  19.     private MediaPlayer player;  
  20.     private Timer timer;  
  21.   
  22.     //綁定服務時,調用此方法  
  23.     @Nullable  
  24.     @Override  
  25.     public IBinder onBind(Intent intent) {  
  26.   
  27.         return new MusicControl();  
  28.     }  
  29.   
  30.     //創建播放音樂的服務  
  31.     @Override  
  32.     public void onCreate() {  
  33.         super.onCreate();  
  34.   
  35.         //創建音樂播放器對象  
  36.         player = new MediaPlayer();  
  37.     }  
  38.   
  39.     //銷燬播放音樂服務  
  40.     @Override  
  41.     public void onDestroy() {  
  42.         super.onDestroy();  
  43.   
  44.         //停止播放音樂  
  45.         player.stop();  
  46.   
  47.         //釋放佔用的資源  
  48.         player.release();  
  49.   
  50.         //將player置爲空  
  51.         player = null;  
  52.     }  
  53.   
  54.     //播放音樂  
  55.     public void play() {  
  56.   
  57.         try {  
  58.   
  59.             if(player == null)  
  60.             {  
  61.                 player = new MediaPlayer();  
  62.             }  
  63.   
  64.             //重置  
  65.             player.reset();  
  66.   
  67.             //加載多媒體文件  
  68.             player.setDataSource("sdcard/zxmzf.mp3");  
  69.   
  70.             //準備播放音樂  
  71.             player.prepare();  
  72.   
  73.             //播放音樂  
  74.             player.start();  
  75.   
  76.             //添加計時器  
  77.             addTimer();  
  78.   
  79.         } catch (IOException e) {  
  80.             e.printStackTrace();  
  81.         }  
  82.     }  
  83.   
  84.     //暫停播放音樂  
  85.     public void pausePlay() {  
  86.   
  87.         player.pause();  
  88.     }  
  89.   
  90.     //繼續播放音樂  
  91.     public void continuePlay() {  
  92.   
  93.         player.start();  
  94.     }  
  95.   
  96.     //創建一個實現音樂接口的音樂控制類  
  97.     class MusicControl extends Binder implements MusicInterface {  
  98.   
  99.         @Override  
  100.         public void play() {  
  101.   
  102.             MusicService.this.play();  
  103.         }  
  104.   
  105.         @Override  
  106.         public void pausePlay() {  
  107.   
  108.             MusicService.this.pausePlay();  
  109.         }  
  110.   
  111.         @Override  
  112.         public void continuePlay() {  
  113.   
  114.             MusicService.this.continuePlay();  
  115.         }  
  116.   
  117.         @Override  
  118.         public void seekTo(int progress) {  
  119.   
  120.             MusicService.this.seekTo(progress);  
  121.         }  
  122.     }  
  123.   
  124.     //設置音樂的播放位置  
  125.     public void seekTo(int progress) {  
  126.   
  127.         player.seekTo(progress);  
  128.     }  
  129.   
  130.     //添加計時器用於設置音樂播放器中的播放進度  
  131.     public void addTimer() {  
  132.   
  133.         //如果沒有創建計時器對象  
  134.         if(timer == null) {  
  135.   
  136.             //創建計時器對象  
  137.             timer = new Timer();  
  138.   
  139.             timer.schedule(new TimerTask() {  
  140.   
  141.                 //執行計時任務  
  142.                 @Override  
  143.                 public void run() {  
  144.   
  145.                     //獲得歌曲總時長  
  146.                     int duration = player.getDuration();  
  147.   
  148.                     //獲得歌曲的當前播放進度  
  149.                     int currentPosition = player.getCurrentPosition();  
  150.   
  151.                     //創建消息對象  
  152.                     Message msg = MainActivity.handler.obtainMessage();  
  153.   
  154.                     //將音樂的播放進度封裝至消息對象中  
  155.                     Bundle bundle = new Bundle();  
  156.                     bundle.putInt("duration", duration);  
  157.                     bundle.putInt("currentPosition", currentPosition);  
  158.                     msg.setData(bundle);  
  159.   
  160.                     //將消息發送到主線程的消息隊列  
  161.                     MainActivity.handler.sendMessage(msg);  
  162.                 }  
  163.             },  
  164.   
  165.             //開始計時任務後的5毫秒,第一次執行run方法,以後每500毫秒執行一次  
  166.             5500);  
  167.         }  
  168.     }  
  169. }  

第三步:創建一個MusicInterface.java文件創建用於操作音樂播放的接口

[java] view plain copy
  1. package com.fyt.musicplayer;  
  2.   
  3. //創建一個音樂播放接口  
  4. public interface MusicInterface {  
  5.   
  6.     //播放音樂  
  7.     void play();  
  8.   
  9.     //暫停播放音樂  
  10.     void pausePlay();  
  11.   
  12.     //繼續播放音樂  
  13.     void continuePlay();  
  14.   
  15.     //修改音樂的播放位置  
  16.     void seekTo(int progress);  
  17. }  


第四步:修改MainActivity.java文件

[java] view plain copy
  1. package com.fyt.musicplayer;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.ComponentName;  
  5. import android.content.Intent;  
  6. import android.content.ServiceConnection;  
  7. import android.os.Bundle;  
  8. import android.os.Handler;  
  9. import android.os.IBinder;  
  10. import android.os.Message;  
  11. import android.view.View;  
  12. import android.widget.SeekBar;  
  13. import android.widget.TextView;  
  14.   
  15. public class MainActivity extends Activity {  
  16.   
  17.     MyServiceConn conn;  
  18.     Intent intent;  
  19.     MusicInterface mi;  
  20.   
  21.     //用於設置音樂播放器的播放進度  
  22.     private static SeekBar sb;  
  23.   
  24.     private static TextView tv_progress;  
  25.     private static TextView tv_total;  
  26.   
  27.     @Override  
  28.     protected void onCreate(Bundle savedInstanceState) {  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.activity_main);  
  31.   
  32.         tv_progress = (TextView) findViewById(R.id.tv_progress);  
  33.         tv_total = (TextView) findViewById(R.id.tv_total);  
  34.   
  35.         //創建意圖對象  
  36.         intent = new Intent(this, MusicService.class);  
  37.   
  38.         //啓動服務  
  39.         startService(intent);  
  40.   
  41.         //創建服務連接對象  
  42.         conn = new MyServiceConn();  
  43.   
  44.         //綁定服務  
  45.         bindService(intent, conn, BIND_AUTO_CREATE);  
  46.   
  47.         //獲得佈局文件上的滑動條  
  48.         sb = (SeekBar) findViewById(R.id.sb);  
  49.   
  50.         //爲滑動條添加事件監聽  
  51.         sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {  
  52.   
  53.             //當滑動條中的進度改變後,此方法被調用  
  54.             @Override  
  55.             public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {  
  56.   
  57.             }  
  58.   
  59.             //滑動條剛開始滑動,此方法被調用  
  60.             @Override  
  61.             public void onStartTrackingTouch(SeekBar seekBar) {  
  62.   
  63.             }  
  64.   
  65.             //當滑動條停止滑動,此方法被調用  
  66.             @Override  
  67.             public void onStopTrackingTouch(SeekBar seekBar) {  
  68.   
  69.                 //根據拖動的進度改變音樂播放進度  
  70.                 int progress = seekBar.getProgress();  
  71.   
  72.                 //改變播放進度  
  73.                 mi.seekTo(progress);  
  74.             }  
  75.         });  
  76.     }  
  77.   
  78.     //創建消息處理器對象  
  79.     public static Handler handler = new Handler(){  
  80.   
  81.         //在主線程中處理從子線程發送過來的消息  
  82.         @Override  
  83.         public void handleMessage(Message msg) {  
  84.   
  85.             //獲取從子線程發送過來的音樂播放的進度  
  86.             Bundle bundle = msg.getData();  
  87.   
  88.             //歌曲的總時長(毫秒)  
  89.             int duration = bundle.getInt("duration");  
  90.   
  91.             //歌曲的當前進度(毫秒)  
  92.             int currentPostition = bundle.getInt("currentPosition");  
  93.   
  94.             //刷新滑塊的進度  
  95.             sb.setMax(duration);  
  96.             sb.setProgress(currentPostition);  
  97.   
  98.             //歌曲的總時長  
  99.             int minute = duration / 1000 / 60;  
  100.             int second = duration / 1000 % 60;  
  101.   
  102.             String strMinute = null;  
  103.             String strSecond = null;  
  104.   
  105.             //如果歌曲的時間中的分鐘小於10  
  106.             if(minute < 10) {  
  107.   
  108.                 //在分鐘的前面加一個0  
  109.                 strMinute = "0" + minute;  
  110.             } else {  
  111.   
  112.                 strMinute = minute + "";  
  113.             }  
  114.   
  115.             //如果歌曲的時間中的秒鐘小於10  
  116.             if(second < 10)  
  117.             {  
  118.                 //在秒鐘前面加一個0  
  119.                 strSecond = "0" + second;  
  120.             } else {  
  121.   
  122.                 strSecond = second + "";  
  123.             }  
  124.   
  125.             tv_total.setText(strMinute + ":" + strSecond);  
  126.   
  127.             //歌曲當前播放時長  
  128.             minute = currentPostition / 1000 / 60;  
  129.             second = currentPostition / 1000 % 60;  
  130.   
  131.             //如果歌曲的時間中的分鐘小於10  
  132.             if(minute < 10) {  
  133.   
  134.                 //在分鐘的前面加一個0  
  135.                 strMinute = "0" + minute;  
  136.             } else {  
  137.   
  138.                 strMinute = minute + "";  
  139.             }  
  140.   
  141.             //如果歌曲的時間中的秒鐘小於10  
  142.             if(second < 10) {  
  143.   
  144.                 //在秒鐘前面加一個0  
  145.                 strSecond = "0" + second;  
  146.             } else {  
  147.   
  148.                 strSecond = second + "";  
  149.             }  
  150.   
  151.             tv_progress.setText(strMinute + ":" + strSecond);  
  152.         }  
  153.     };  
  154.   
  155.     //播放音樂按鈕響應函數  
  156.     public void play(View view) {  
  157.   
  158.         //播放音樂  
  159.         mi.play();  
  160.     }  
  161.   
  162.     //暫停播放音樂按鈕響應函數  
  163.     public void pausePlay(View view) {  
  164.   
  165.         //暫停播放音樂  
  166.         mi.pausePlay();  
  167.     }  
  168.   
  169.     //繼續播放音樂按鈕響應函數  
  170.     public void continuePlay (View view) {  
  171.   
  172.         //繼續播放音樂  
  173.         mi.continuePlay();  
  174.     }  
  175.   
  176.     //退出音樂播放按鈕響應函數  
  177.     public void exit(View view) {  
  178.   
  179.         //解綁服務  
  180.         unbindService(conn);  
  181.   
  182.         //停止服務  
  183.         stopService(intent);  
  184.   
  185.         //結束這個activity  
  186.         finish();  
  187.     }  
  188.   
  189.     //實現服務器連接接口  
  190.     class MyServiceConn implements ServiceConnection {  
  191.   
  192.         @Override  
  193.         public void onServiceConnected(ComponentName name, IBinder service) {  
  194.   
  195.             //獲得中間人對象  
  196.             mi = (MusicInterface) service;  
  197.         }  
  198.   
  199.         @Override  
  200.         public void onServiceDisconnected(ComponentName name) {  
  201.   
  202.         }  
  203.     }  
  204. }  


第五步:在配置文件中的Application節點下添加服務組件

[html] view plain copy
  1. <service android:name="com.fyt.playmusic.MusicService">  
  2.         </service>  

最後一步:添加讀取SD卡的權限

[html] view plain copy
  1. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章