制作一个简单的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"/>  

猜你喜欢

转载自blog.csdn.net/Duanmuyang/article/details/80103199
今日推荐