音樂播放器是一個非常常見的應用,這篇博客就是介紹如何製作一個簡單的音樂播放器,這款音樂播放器具有以下的功能:播放歌曲、暫停播放歌曲、、顯示歌曲的總時長、顯示歌曲的當前播放時長、調節滑塊可以將歌曲調節到任何時間播放、退出音樂播放器
實現效果如下
實現方式:
第一步:使用Android Studio創建一個Android工程,並且修改activity_main.xml文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.fyt.musicplayer.MainActivity"
- android:orientation="vertical">
- <!--顯示播放進度-->
- <SeekBar
- android:id="@+id/sb"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <!--顯示當前進度-->
- <TextView
- android:id="@+id/tv_progress"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="00:00"/>
- <!--顯示總進度-->
- <TextView
- android:id="@+id/tv_total"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:text="00:00"/>
- </RelativeLayout>
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="播放音樂"
- android:onClick="play"/>
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="暫停播放"
- android:onClick="pausePlay"/>
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="繼續播放"
- android:onClick="continuePlay"/>
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="退出"
- android:onClick="exit"/>
- </LinearLayout>
- package com.fyt.musicplayer;
- import android.app.Service;
- import android.content.Intent;
- import android.media.MediaPlayer;
- import android.os.Binder;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.Message;
- import android.support.annotation.Nullable;
- import java.io.IOException;
- import java.util.Timer;
- import java.util.TimerTask;
- //創建一個繼承自服務的音樂服務類
- public class MusicService extends Service {
- private MediaPlayer player;
- private Timer timer;
- //綁定服務時,調用此方法
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return new MusicControl();
- }
- //創建播放音樂的服務
- @Override
- public void onCreate() {
- super.onCreate();
- //創建音樂播放器對象
- player = new MediaPlayer();
- }
- //銷燬播放音樂服務
- @Override
- public void onDestroy() {
- super.onDestroy();
- //停止播放音樂
- player.stop();
- //釋放佔用的資源
- player.release();
- //將player置爲空
- player = null;
- }
- //播放音樂
- public void play() {
- try {
- if(player == null)
- {
- player = new MediaPlayer();
- }
- //重置
- player.reset();
- //加載多媒體文件
- player.setDataSource("sdcard/zxmzf.mp3");
- //準備播放音樂
- player.prepare();
- //播放音樂
- player.start();
- //添加計時器
- addTimer();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- //暫停播放音樂
- public void pausePlay() {
- player.pause();
- }
- //繼續播放音樂
- public void continuePlay() {
- player.start();
- }
- //創建一個實現音樂接口的音樂控制類
- class MusicControl extends Binder implements MusicInterface {
- @Override
- public void play() {
- MusicService.this.play();
- }
- @Override
- public void pausePlay() {
- MusicService.this.pausePlay();
- }
- @Override
- public void continuePlay() {
- MusicService.this.continuePlay();
- }
- @Override
- public void seekTo(int progress) {
- MusicService.this.seekTo(progress);
- }
- }
- //設置音樂的播放位置
- public void seekTo(int progress) {
- player.seekTo(progress);
- }
- //添加計時器用於設置音樂播放器中的播放進度
- public void addTimer() {
- //如果沒有創建計時器對象
- if(timer == null) {
- //創建計時器對象
- timer = new Timer();
- timer.schedule(new TimerTask() {
- //執行計時任務
- @Override
- public void run() {
- //獲得歌曲總時長
- int duration = player.getDuration();
- //獲得歌曲的當前播放進度
- int currentPosition = player.getCurrentPosition();
- //創建消息對象
- Message msg = MainActivity.handler.obtainMessage();
- //將音樂的播放進度封裝至消息對象中
- Bundle bundle = new Bundle();
- bundle.putInt("duration", duration);
- bundle.putInt("currentPosition", currentPosition);
- msg.setData(bundle);
- //將消息發送到主線程的消息隊列
- MainActivity.handler.sendMessage(msg);
- }
- },
- //開始計時任務後的5毫秒,第一次執行run方法,以後每500毫秒執行一次
- 5, 500);
- }
- }
- }
第三步:創建一個MusicInterface.java文件創建用於操作音樂播放的接口
- package com.fyt.musicplayer;
- //創建一個音樂播放接口
- public interface MusicInterface {
- //播放音樂
- void play();
- //暫停播放音樂
- void pausePlay();
- //繼續播放音樂
- void continuePlay();
- //修改音樂的播放位置
- void seekTo(int progress);
- }
- package com.fyt.musicplayer;
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.view.View;
- import android.widget.SeekBar;
- import android.widget.TextView;
- public class MainActivity extends Activity {
- MyServiceConn conn;
- Intent intent;
- MusicInterface mi;
- //用於設置音樂播放器的播放進度
- private static SeekBar sb;
- private static TextView tv_progress;
- private static TextView tv_total;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- tv_progress = (TextView) findViewById(R.id.tv_progress);
- tv_total = (TextView) findViewById(R.id.tv_total);
- //創建意圖對象
- intent = new Intent(this, MusicService.class);
- //啓動服務
- startService(intent);
- //創建服務連接對象
- conn = new MyServiceConn();
- //綁定服務
- bindService(intent, conn, BIND_AUTO_CREATE);
- //獲得佈局文件上的滑動條
- sb = (SeekBar) findViewById(R.id.sb);
- //爲滑動條添加事件監聽
- sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
- //當滑動條中的進度改變後,此方法被調用
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- }
- //滑動條剛開始滑動,此方法被調用
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
- //當滑動條停止滑動,此方法被調用
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- //根據拖動的進度改變音樂播放進度
- int progress = seekBar.getProgress();
- //改變播放進度
- mi.seekTo(progress);
- }
- });
- }
- //創建消息處理器對象
- public static Handler handler = new Handler(){
- //在主線程中處理從子線程發送過來的消息
- @Override
- public void handleMessage(Message msg) {
- //獲取從子線程發送過來的音樂播放的進度
- Bundle bundle = msg.getData();
- //歌曲的總時長(毫秒)
- int duration = bundle.getInt("duration");
- //歌曲的當前進度(毫秒)
- int currentPostition = bundle.getInt("currentPosition");
- //刷新滑塊的進度
- sb.setMax(duration);
- sb.setProgress(currentPostition);
- //歌曲的總時長
- int minute = duration / 1000 / 60;
- int second = duration / 1000 % 60;
- String strMinute = null;
- String strSecond = null;
- //如果歌曲的時間中的分鐘小於10
- if(minute < 10) {
- //在分鐘的前面加一個0
- strMinute = "0" + minute;
- } else {
- strMinute = minute + "";
- }
- //如果歌曲的時間中的秒鐘小於10
- if(second < 10)
- {
- //在秒鐘前面加一個0
- strSecond = "0" + second;
- } else {
- strSecond = second + "";
- }
- tv_total.setText(strMinute + ":" + strSecond);
- //歌曲當前播放時長
- minute = currentPostition / 1000 / 60;
- second = currentPostition / 1000 % 60;
- //如果歌曲的時間中的分鐘小於10
- if(minute < 10) {
- //在分鐘的前面加一個0
- strMinute = "0" + minute;
- } else {
- strMinute = minute + "";
- }
- //如果歌曲的時間中的秒鐘小於10
- if(second < 10) {
- //在秒鐘前面加一個0
- strSecond = "0" + second;
- } else {
- strSecond = second + "";
- }
- tv_progress.setText(strMinute + ":" + strSecond);
- }
- };
- //播放音樂按鈕響應函數
- public void play(View view) {
- //播放音樂
- mi.play();
- }
- //暫停播放音樂按鈕響應函數
- public void pausePlay(View view) {
- //暫停播放音樂
- mi.pausePlay();
- }
- //繼續播放音樂按鈕響應函數
- public void continuePlay (View view) {
- //繼續播放音樂
- mi.continuePlay();
- }
- //退出音樂播放按鈕響應函數
- public void exit(View view) {
- //解綁服務
- unbindService(conn);
- //停止服務
- stopService(intent);
- //結束這個activity
- finish();
- }
- //實現服務器連接接口
- class MyServiceConn implements ServiceConnection {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- //獲得中間人對象
- mi = (MusicInterface) service;
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- }
- }
第五步:在配置文件中的Application節點下添加服務組件
- <service android:name="com.fyt.playmusic.MusicService">
- </service>
最後一步:添加讀取SD卡的權限
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>