简洁音乐播放器(Android优化版)

运行结果:

这里写图片描述

具体实现步骤:

Step1: activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:background="@mipmap/bg"
    tools:context="com.victor.a1000phone.mysonymusicplayer.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="播放列表"
        android:textSize="28sp"
        android:id="@+id/txt_title"
        android:textColor="#ffffff"
        android:layout_centerHorizontal="true"/>


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="80dp"
        android:text="00:00"
        android:id="@+id/txt_currentTime"
        android:textColor="#ffffff"
        android:textSize="19sp"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#ffffff"
        android:textSize="19sp"
        android:id="@+id/txt_totalTime"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:text="00:00"
        android:layout_marginBottom="80dp"/>

    <SeekBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/seekbar"
        android:layout_toRightOf="@id/txt_currentTime"
        android:layout_alignParentBottom="true"
        android:layout_toLeftOf="@id/txt_totalTime"
        android:layout_marginBottom="80dp"/>
    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lv_musicList"
        android:layout_below="@id/txt_title"
        android:layout_margin="8dp"
        android:layout_above="@id/txt_currentTime">
    </ListView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true"
        android:gravity="center"
        android:layout_marginBottom="2dp">
        <Button
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:id="@+id/btn_back"
            android:layout_margin="10dp"
            android:background="@mipmap/back"
            android:onClick="onClick"/>

        <Button
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:id="@+id/btn_pause"
            android:background="@mipmap/begin"
            android:layout_margin="10dp"
            android:onClick="onClick"/>
        <Button
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:id="@+id/btn_stop"
            android:background="@mipmap/stop"
            android:layout_margin="10dp"
            android:onClick="onClick"/>

        <Button
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:id="@+id/btn_next"
            android:background="@mipmap/next"
            android:layout_margin="10dp"
            android:onClick="onClick"/>
    </LinearLayout>


</RelativeLayout>

Step2: MainActivity.java

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Environment;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;

import java.io.File;
import java.io.FileFilter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements ServiceConnection {
    private File[] musicFile;
    private ListView mLvMusicList;
    private List<String> musics = new ArrayList<>();
    ;
    private ArrayAdapter<String> adapter;

    private PlayMusicService playMusicService;

    private Button mBtnPause;
    private TextView mTxtMusicTotalTime, mTxtMusicCurrentTime;

    //暂停或继续播放的标志位
    private boolean isGoOn = false;
    //时间存储变量
    private int totalTime;
    private int currentTime;

    private SeekBar mseekBar;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        musicFile = getMusicFiles();
        initView();

        //绑定Service
        Intent intent = new Intent(this, PlayMusicService.class);
        intent.putExtra("musicFiles", new MusicFiles(musicFile));
        boolean isBindSuccess = bindService(intent, this, Context.BIND_AUTO_CREATE);
        Log.i("1607", isBindSuccess + "");

        //注册接受音乐时长的广播接收器
        MusicDurationReceiver musicDurationReceiver = new MusicDurationReceiver();
        IntentFilter intentFilterMusicduration = new IntentFilter();
        intentFilterMusicduration.addAction("com.musicTime");
        registerReceiver(musicDurationReceiver, intentFilterMusicduration);
        //注册接受音乐当前时长的广播接收器
        MusicPositionReceiver musicPositionReceiver = new MusicPositionReceiver();
        IntentFilter intentFilterMusicCurrent = new IntentFilter();
        intentFilterMusicCurrent.addAction("com.current");
        registerReceiver(musicPositionReceiver, intentFilterMusicCurrent);


    }

    private void initView() {
        mLvMusicList = (ListView) findViewById(R.id.lv_musicList);
        mBtnPause = (Button) findViewById(R.id.btn_pause);
        mTxtMusicTotalTime = (TextView) findViewById(R.id.txt_totalTime);
        mTxtMusicCurrentTime = (TextView) findViewById(R.id.txt_currentTime);
        mseekBar = (SeekBar) findViewById(R.id.seekbar);

        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, musics);
        mLvMusicList.setAdapter(adapter);
        mLvMusicList.setOnItemClickListener(listener);

        mseekBar.setOnSeekBarChangeListener(listenerSeekBar);
    }

    /**
     * SeekBar的监听器
     */
    SeekBar.OnSeekBarChangeListener listenerSeekBar = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            Log.i("1607", "Seekbar被改变的进度为:" + seekBar.getProgress());
            if (fromUser){
                int currentPase = seekBar.getProgress() * totalTime / 100;

                Intent intent=new Intent("com.currentPase");
                intent.putExtra("currentPase",currentPase);
                sendBroadcast(intent);
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

            Log.i("1607", "Seekbar被拖动的进度为:" + seekBar.getProgress());

        }
    };

    /**
     * ListView 的点击监听
     */
    AdapterView.OnItemClickListener listener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            isGoOn = true;
            mBtnPause.setBackgroundResource(R.mipmap.pause);
            playMusicService.prepareMusic(position);
            //将用户的选择通过广播传到Service中
            Intent intent = new Intent();
            intent.setAction("com.userChooseMusic");
            intent.putExtra("position", position);
            sendBroadcast(intent);

        }
    };

    private File[] getMusicFiles() {
        File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "myplaylist"
                + File.separator + "audios");

        musicFile = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                String fileName = pathname.getName();
                if (fileName.endsWith(".mp3")) {
                    musics.add(fileName);
                    return true;
                } else {
                    return false;
                }
            }
        });
        return musicFile;
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_back://上一曲
                playMusicService.back();
                break;

            case R.id.btn_pause://暂停或继续播放
                isGoOn = !isGoOn;
                if (isGoOn) {
                    mBtnPause.setBackgroundResource(R.mipmap.pause);
                    playMusicService.startMusic();
                } else {
                    mBtnPause.setBackgroundResource(R.mipmap.begin);
                    playMusicService.pauseMusic();
                }
                break;

            case R.id.btn_stop://停止
                playMusicService.stopMusic();
                mTxtMusicTotalTime.setText("00:00");
                break;

            case R.id.btn_next://下一曲
                playMusicService.next();
                break;
        }
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        PlayMusicService.MyService service1 = (PlayMusicService.MyService) service;
        playMusicService = service1.getService();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }

    /**
     * @param time int类型,从Service端获取
     * @return 音乐播放时间,格式为:00:00
     */
    public String getTimeFormat(int time) {
        SimpleDateFormat format = new SimpleDateFormat("mm:ss");
        String musicTime = format.format(time);
        return musicTime;
    }

    //=============================来自PlayMusicService发送来的广播监听器============================

    /**
     * 接受音乐总时长的监听器
     */
    class MusicDurationReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            totalTime = intent.getIntExtra("musicTime", 0);
            String totalTimeShow = getTimeFormat(totalTime);
            mTxtMusicTotalTime.setText(totalTimeShow);
        }
    }

    /**
     * 接受音乐当前进度的监听器
     */
    class MusicPositionReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            currentTime = intent.getIntExtra("currentPositionMusic", 0);
            String current = getTimeFormat(currentTime);
            mTxtMusicCurrentTime.setText(current);

            //计算当前的SeekBar应该显示的进度
            double currentRate = currentTime / (double) (totalTime);
            double progressDouble = currentRate * 100;
            mseekBar.setProgress((int) progressDouble);
        }
    }
}

Step3 : MusicFiles.java

import java.io.File;
import java.io.Serializable;

/**
 * Created by Victor on 2016/9/23.
 */
public class MusicFiles implements Serializable {
    public File[] musicFiles;

    public MusicFiles(File[] musicFiles){
        this.musicFiles=musicFiles;
    }

    public File[] getMusicFiles() {
        return musicFiles;
    }



}

Step4 : PlayMusicService.java

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;

/**
 * Created by Administrator on 2016/9/23.
 */
public class PlayMusicService extends Service {

    private MediaPlayer mediaPlayer;
    private int currentPosition = 0;
    private boolean isStop = true;
    private File[] musicFiles;

    private int musicDuration;
    private int currentPositionMusic;

    public PlayMusicService() {

    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
        }

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                currentPosition++;
                if (currentPosition == musicFiles.length) {
                    currentPosition = 0;
                }
                prepareMusic(currentPosition);

            }
        });

        //注册用户选择音乐位置监听的广播接收者
        UserChooseMusic userChooseMusic = new UserChooseMusic();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.userChooseMusic");
        registerReceiver(userChooseMusic, intentFilter);

        //注册用户拖动SeekBar改变音乐进度的监听器
        CurrentProgressReceiver currentProgressReceiver = new CurrentProgressReceiver();
        IntentFilter intentFilterProgress = new IntentFilter();
        intentFilterProgress.addAction("com.currentPase");
        registerReceiver(currentProgressReceiver, intentFilterProgress);

    }

    /**
     * 重新开始一首歌
     */
    public void prepareMusic(int currentPosition) {
        try {
            mediaPlayer.reset();
            mediaPlayer.setDataSource(musicFiles[currentPosition].getAbsolutePath());
            mediaPlayer.prepare();
            mediaPlayer.start();
            isStop = false;

            //得到歌曲的总时长,并传送给Mainctivity
            musicDuration = mediaPlayer.getDuration();

            //发送广播传递到Mainctivity
            Intent intent = new Intent("com.musicTime");
            intent.putExtra("musicTime", musicDuration);
            sendBroadcast(intent);

            getCurrentPositionOfMusic();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 开启另一个线程,每隔一秒读取MediaPlayer当前的进度:getCurrentPosion
     * 并将进度发送到MainActivity
     */
    private void getCurrentPositionOfMusic() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                currentPositionMusic = mediaPlayer.getCurrentPosition();
                try {
                    while (currentPositionMusic <= musicDuration) {
                        //发送广播,将当前音乐的播放进度发送给MainActivity
                        Intent intent = new Intent("com.current");
                        intent.putExtra("currentPositionMusic", currentPositionMusic);
                        sendBroadcast(intent);
                        currentPositionMusic = mediaPlayer.getCurrentPosition();
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 暂停之后继续播放一首歌
     */
    public void startMusic() {
        if (mediaPlayer != null && !isStop) {
            mediaPlayer.start();
        } else {
            Toast.makeText(this, "您已经停止播放,请选择想要播放的歌曲", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 暂停播放歌曲
     */
    public void pauseMusic() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        } else {
            Toast.makeText(this, "当前没有歌曲在播放", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 停止歌曲
     */
    public void stopMusic() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            isStop = true;
        }
    }

    /**
     * 上一首歌曲
     */
    public void back() {
        if (mediaPlayer != null) {
            currentPosition--;
            if (currentPosition < 0) {
                currentPosition = musicFiles.length - 1;
            }
            prepareMusic(currentPosition);
        }
    }

    /**
     * 下一首歌曲
     */
    public void next() {
        if (mediaPlayer != null) {
            currentPosition++;
            if (currentPosition == musicFiles.length) {
                currentPosition = 0;
            }
            prepareMusic(currentPosition);
        }
    }


    class MyService extends Binder {
        public PlayMusicService getService() {
            return PlayMusicService.this;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        musicFiles = ((MusicFiles) (intent.getSerializableExtra("musicFiles"))).getMusicFiles();
        return new MyService();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    //======================================广播接收器=================================
    class UserChooseMusic extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            currentPosition = intent.getIntExtra("position", 0);
            Log.i("1607", "用户选择的是第" + currentPosition + "首歌");
        }
    }

    class CurrentProgressReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            int currentProgress = intent.getIntExtra("currentPase", 0);

            //将音乐播放器移至currentProgress进度处
            mediaPlayer.seekTo(currentProgress);

        }
    }
}

Step5 : AndroidManifest.xml**(这里的设置非常重要,决定能不能成功运行)**

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.victor.a1000phone.mysonymusicplayer">

    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".PlayMusicService"
            android:exported="true"
            android:enabled="true"/>
    </application>

</manifest>

Step6 :环境配置

模拟器:

1.如果你用模拟器运行,就建立一个”mymusiclist”文件夹, 里面再建一个”audios”文件夹.
2.把你的MP3文件全部放到”audios”文件夹中。
3.把“mymusiclist”文件夹拖到“sdcard”文件夹中。如图***
4.运行项目程序

这里写图片描述

这里写图片描述

自己的手机

1.在SD卡根目录下建立一个”mymusiclist”文件夹, 里面再建一个”audios”文件夹.
2.把你的MP3文件全部放到”audios”文件夹中。
3.运行项目程序

PS: 代码里有每个模块的注释,在这里就不啰嗦了。大家有不明白的地方可以留言哈,一起讨论,一起进步。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值