基于安卓平台音乐播放器的设计与实现

目 录
摘 要 I
Abstract II
1 绪论 1
1.1研究目的与意义 1
1.2研究概况 1
1.3 论文的主要工作 3
1.4 论文的结构 3
2开发技术及工具的介绍 5
2.1 安卓平台简介 5
2.2 Retrofit技术框架 7
2.3RxJava技术框架 7
2.4MVP框架技术简介 8
2.5安卓平台 AndroidStudio开发工具简介 8
2.6 IntelliJ IDEA开发工具简介 9
2.7PowerDesign工具介绍 10
2.8Rotation Rose简介 10
2.9Spring-boot技术简介 11
2.10Mysql数据库简介 11
2.11Glide框架 12
2.12Mybatis 13
3需求分析 14
3.1系统概述 14
3.2系统分析 14
3.2.1系统需求分析 14
3.2.2系统可行性分析 14
3.2.3系统用力模型分析 15
3.3系统用例分析 18
3.4领域涉及模型 20
4系统设计 21
4.1概念模型 21
4.2物理模型 22
4.3 数据库设计 23
4.4 目录结构设计 26
4.4.1RUP面向对象设计模式的可视化建模 26
4.4.2客户端工程文件目录图 26
4.4.3服务端工程文件目录图 28
5系统详细设计 30
5.1播放音乐时序图 30
5.2系统界面及其核心代码 31
6系统测试 52
6.1 软件测试常识及主要技术 52
6.2.测试用例及结果 53
6.2.1播放音乐 53
6.2.2评论歌曲 55
6.2.3下载歌曲 56
7结论 59
7.1启示和意义 59
7.2局限性 59
7.3展望 59
参考文献 60
致 谢 61
3需求分析
3.1系统概述
本系统主要的用户为广大的安卓平台手机用户提供音乐播放,歌曲下载,歌迷互动三大模块功能。
3.2系统分析
3.2.1系统需求分析
随着安卓平台和移动互联网的快速崛起,手机已经成为人们生活不可缺的一部分,在现代人的生活中,人们生活节奏的加快,生活压力越来越大,碎片化的时间越来越多,那么一个可以在碎片化的时间内调节自己心情的产品,无疑将拥有一个巨大的市场,而基于安卓平台的手机音乐播放器就能很好地满足这个需求。
通过调查分析,本系统的用户为广大的安卓平台手机用户,用户可以通过本系统实现音乐播放的基本功能包括播放,暂停,上一首,下一首等。用户还可以分享歌曲,对歌曲进行评论或者点赞别人的评论,下载歌曲,具体需求如下:
(1)音乐播放,音乐播放包括了音乐播放的基本功能:开始,暂停,上一首,下一首,同时还可以滑动唱片来实现切换上下首,通过拖动进度条来切换到音乐的不同位置。
(2)歌曲下载,首先用户需要搜索所需要的歌曲,然后点击下载。同时用户可以搜索不同平台的歌曲,这样就可以不会因为不同版权而听不到音乐。
(3)乐迷互动,用户可以通过在播放页面的评论按钮评论歌曲,进入评论界面后还可以对自己喜欢的评论进行点赞或者评论,同时歌迷也可以通过分享到第三方平台一起享受音乐带来的乐趣。

package com.monk.player;

import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.example.andy.player.R;
import com.monk.player.aidl.IMusicPlayer;
import com.monk.player.aidl.MusicPlayListner;
import com.monk.player.aidl.SongBean;
import com.monk.player.application.MyApplication;
import com.monk.player.interfaces.IplayStatus;
import com.monk.player.mvp.base.MvpActivity;
import com.monk.player.mvp.paly.PlayPresnter;
import com.monk.player.service.MusicService;
import com.monk.player.tools.DiskDimenUtils;
import com.monk.player.tools.LogUtil;
import com.monk.player.weight.Dislayout;
import com.monk.player.weight.DisplayLayout;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.concurrent.ExecutionException;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import me.wcy.lrcview.LrcView;

public class MainActivity extends MvpActivity<PlayPresnter> implements IplayStatus {
    
    
    private static final String TAG = "MainActivity";
    public Handler handler;
    @BindView(R.id.ivCi)
    ImageView ivCi;
    @BindView(R.id.ivMenu)
    ImageView ivMenu;
    private Dislayout.MusicStatus musicStatus = Dislayout.MusicStatus.PAUSE;
    @BindView(R.id.play_disc_backgound)
    ImageView playDiscBackgound;
    @BindView(R.id.play_discContain)
    ViewPager playDiscContain;
    @BindView(R.id.play_needle)
    ImageView playNeedle;
    @BindView(R.id.tvCurrentTime)
    TextView tvCurrentTime;
    @BindView(R.id.musicSeekBar)
    SeekBar musicSeekBar;
    @BindView(R.id.tvTotalTime)
    TextView tvTotalTime;
    @BindView(R.id.rlMusicTime)
    RelativeLayout rlMusicTime;
    @BindView(R.id.ivLast)
    ImageView ivLast;
    @BindView(R.id.ivPlayOrPause)
    ImageView ivPlayOrPause;
    @BindView(R.id.ivNext)
    ImageView ivNext;
    @BindView(R.id.llPlayOption)
    LinearLayout llPlayOption;
    @BindView(R.id.set_freground)
    DisplayLayout setFreground;
    Dislayout dislayout;
    LrcView lrcView;
    private Bitmap[] bitmaps = new Bitmap[3];
    private int index = 0;
    private String[] m4as = {
    
    "com.monk.player.http://ws.stream.qqmusic.qq.com/200790315.m4a?fromtag=46",
            "com.monk.player.http://ws.stream.qqmusic.qq.com/7416139.m4a?fromtag=46",
            "com.monk.player.http://ws.stream.qqmusic.qq.com/7168586.m4a?fromtag=46"};
    private Unbinder unbinder;
    private IMusicPlayer mMusicService;
    private SimpleDateFormat mFormatter = new SimpleDateFormat("mm:ss");
    private MusicPlayListner listner = new MusicPlayListner.Stub() {
    
    
        @Override
        public void action(int actioncode, Message message,SongBean songBean) throws RemoteException {
    
    
            mHandler.sendMessage(message);
        }
    };
    private Handler mHandler = new Handler() {
    
    
        @Override
        public void handleMessage(Message msg) {
    
    
            super.handleMessage(msg);
            switch (msg.what) {
    
    
                case MusicService.MUSIC_ACTION_SEEK_PLAY:
                    if (!musicSeekBar.isPressed())
                        updateProgerss(msg);
                    break;
                case MusicService.MUSIC_ACTION_PLAY:

                    break;
                case MusicService.MUSIC_ACTION_COMPLETE:
                    LogUtil.doLog("handleMessage", "COMPLETE");
                    ivNext.performClick();
                    break;
                default:
                    super.handleMessage(msg);
            }

        }
    };

    //更新进度条
    private void updateProgerss(Message msg) {
    
    
        LogUtil.doLog("updateProgerssInMain", "");
        int currentPosition = msg.arg1;
        int totalDuration = msg.arg2;
        lrcView.updateTime(currentPosition);
        tvTotalTime.setText(mFormatter.format(totalDuration));
        tvCurrentTime.setText(mFormatter.format(currentPosition));
        musicSeekBar.setMax(totalDuration);
        musicSeekBar.setProgress(currentPosition);
    }


    @Override
    protected void initData() {
    
    
        super.initData();
        //隐藏状态栏
        if (Build.VERSION.SDK_INT >= 21) {
    
    
            View decorView = getWindow().getDecorView();
            int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            decorView.setSystemUiVisibility(option);
            getWindow().setStatusBarColor(Color.TRANSPARENT);
        }else
        {
    
    
            View decorView = getWindow().getDecorView();
            int option = View.SYSTEM_UI_FLAG_FULLSCREEN;
            decorView.setSystemUiVisibility(option);
        }

        mPresenter.getSongs();
        dislayout = (Dislayout) findViewById(R.id.play_dis_layout);
        dislayout.setpStatus(this);
        lrcView = (LrcView) findViewById(R.id.lrc_view);
        Log.d(TAG, "onCreate: " + System.currentTimeMillis());
        unbinder = ButterKnife.bind(this);
        //使用异步线程加载Bitmap
        loadBitmap();
        mHandler.postDelayed(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                mMusicService = MyApplication.myApplication.getMusicPlayerService();
                LogUtil.doLog("onCreate", "------------" + mMusicService.toString());
                try {
    
    
                    mMusicService.registListner(listner);
                    setFreground.setForeground(DiskDimenUtils.getForegroundDrawable(bitmaps[0], getApplicationContext()));
                    setFreground.beginAnimation();
                } catch (RemoteException e) {
    
    
                    e.printStackTrace();
                }
            }
        }, 1000);

        lrcView.loadLrc(getLrcText("chengdu.lrc"));
        lrcView.updateTime(0);
    }


    public void loadBitmap(){
    
    
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    bitmaps[0] = Glide.with(getApplicationContext()).load(R.mipmap.ic_music1).asBitmap().centerCrop().into(100,100).get();
                    bitmaps[1] = Glide.with(getApplicationContext()).load(R.mipmap.ic_music2).asBitmap().centerCrop().into(100,100).get();
                    bitmaps[2] = Glide.with(getApplicationContext()).load(R.mipmap.ic_music3).asBitmap().centerCrop().into(100,100).get();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                } catch (ExecutionException e) {
    
    
                    e.printStackTrace();
                }
            }
        }).start();
    }
    @Override
    protected int getLayoutRes() {
    
    
        return R.layout.activity_main;
    }


    @Override
    public void initEvents() {
    
    
        musicSeekBar.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) {
    
    
                Log.d(TAG, "onStopTrackingTouch: " + seekBar.getProgress());
                seekPlaySong(seekBar.getProgress());
            }
        });


        ivCi.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                if(dislayout.getVisibility()==View.VISIBLE)
                {
    
    
                    dislayout.setVisibility(View.INVISIBLE);
                    lrcView.setVisibility(View.VISIBLE);
                }else{
    
    
                    dislayout.setVisibility(View.VISIBLE);
                    lrcView.setVisibility(View.INVISIBLE);
                }
            }
        });
    }

    private void seekPlaySong(int progress) {
    
    
        SongBean songBean = new SongBean();
        songBean.setM4a(m4as[index]);
        songBean.setProgress(progress);
        try {
    
    
            mMusicService.action(MusicService.MUSIC_ACTION_SEEK_PLAY, songBean);
        } catch (RemoteException e) {
    
    
            e.printStackTrace();
        }
    }

    @Override
    protected void onResume() {
    
    
        super.onResume();
    }

    @OnClick({
    
    R.id.ivLast, R.id.ivPlayOrPause, R.id.ivNext})
    public void onViewClicked(View view) {
    
    
        switch (view.getId()) {
    
    
            case R.id.ivLast:
                if (index != 0) {
    
    
                    index--;
                    LogUtil.doLog("onViewClicked", "IVLAST" + index);
                    setFreground.setForeground(DiskDimenUtils.getForegroundDrawable(bitmaps[index], this));
                    setFreground.beginAnimation();
                    dislayout.toLast();
                    musicSeekBar.setProgress(0);
                    pause();
                    palyOrPause();

                }
                break;
            case R.id.ivPlayOrPause:
                palyOrPause();
                break;
            case R.id.ivNext:
                if (index != 2) {
    
    
                    index++;
                    LogUtil.doLog("onViewClicked", "IVNEXT" + index);
                    setFreground.setForeground(DiskDimenUtils.getForegroundDrawable(bitmaps[index], this));
                    setFreground.beginAnimation();
                    dislayout.toNext();
                    musicSeekBar.setProgress(0);
                    pause();
                    palyOrPause();
                }
                break;
        }
    }

    @Override
    protected void onDestroy() {
    
    
        unbinder.unbind();
        super.onDestroy();
    }

    @Override
    public void toNext() {
    
    
        if (index != 2) {
    
    
            index++;
            LogUtil.doLog("onViewClicked", "" + index);
            setFreground.setForeground(DiskDimenUtils.getForegroundDrawable(bitmaps[index], this));
            setFreground.beginAnimation();
            musicSeekBar.setProgress(0);
            pause();
            palyOrPause();
        }
    }

    @Override
    public void toLast() {
    
    
        if (index != 0) {
    
    
            index--;
            LogUtil.doLog("onViewClicked", "" + index);
            setFreground.setForeground(DiskDimenUtils.getForegroundDrawable(bitmaps[index], this));
            setFreground.beginAnimation();
            musicSeekBar.setProgress(0);
            pause();
            palyOrPause();
        }
    }

    @Override
    public void pause() {
    
    
        if (musicStatus == Dislayout.MusicStatus.PLAY) {
    
    
            ivPlayOrPause.setImageResource(R.drawable.ic_play);
            musicStatus = Dislayout.MusicStatus.PAUSE;
            dislayout.doPause();
        }
    }

    @Override
    public void play() {
    
    
        LogUtil.doLog("CallbackTOPlay", "" + musicStatus);
        if (musicStatus == Dislayout.MusicStatus.PAUSE) {
    
    
            ivPlayOrPause.setImageResource(R.drawable.ic_pause);
            musicStatus = Dislayout.MusicStatus.PLAY;
            dislayout.doPlay();


        }
    }

    public void palyOrPause() {
    
    
        if (musicStatus == Dislayout.MusicStatus.PLAY) {
    
    
            ivPlayOrPause.setImageResource(R.drawable.ic_play);
            musicStatus = Dislayout.MusicStatus.PAUSE;
            dislayout.doPause();
            try {
    
    
                mMusicService.action(MusicService.MUSIC_ACTION_PAUSE, null);
            } catch (RemoteException e) {
    
    
                e.printStackTrace();
            }


        } else if (musicStatus == Dislayout.MusicStatus.PAUSE) {
    
    
            ivPlayOrPause.setImageResource(R.drawable.ic_pause);
            musicStatus = Dislayout.MusicStatus.PLAY;
            dislayout.doPlay();
            if (musicSeekBar.getProgress() == 0)
                starPalyMusic();
            else
                continuePlayMusic();

        }

    }

    /**
     * 假如进度是0就直接开始
     */
    public void starPalyMusic() {
    
    
        SongBean b = new SongBean();
        b.setM4a(m4as[index]);
        try {
    
    
            mMusicService.action(MusicService.MUSIC_ACTION_PLAY, b);
        } catch (RemoteException e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * 假如进度大于0就continue
     */
    public void continuePlayMusic() {
    
    
        SongBean b = new SongBean();
        b.setM4a(m4as[index]);
        try {
    
    
            mMusicService.action(MusicService.MUSIC_ACTION_CONTINUE_PLAY, b);
        } catch (RemoteException e) {
    
    
            e.printStackTrace();
        }
    }


    @Override
    public PlayPresnter createPresenter() {
    
    
        return new PlayPresnter();
    }

    @Override
    public void showLoading() {
    
    

    }

    @Override
    public void dismissLoading() {
    
    

    }

    /**
     * 查找歌词文件
     *
     * @param fileName
     * @return
     */
    private String getLrcText(String fileName) {
    
    
        String lrcText = null;
        try {
    
    
            InputStream is = getAssets().open(fileName);
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
            lrcText = new String(buffer);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        LogUtil.doLog("getLrcText", "" + lrcText);
        return lrcText;
    }

    public void onloadLyr(String lyric){
    
    
        lrcView.loadLrc(lyric);
        lrcView.updateTime(0);
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/newlw/article/details/131803360