Android音乐播放器(四)音乐唱片的转盘,歌曲同步进度条,以及音乐的暂停/播放/继续/上下歌曲切换

这是去年大二做的一个简单音乐播放器项目:是尽可能模仿酷狗音乐写的,具体实现的功能如下:

1:启动动画:点击运行程序会出现一个两秒钟的视频,类似酷狗音乐的启动动画一样,非常可观!

2:登录注册界面:输入账号和密码检验信息登录!

3:轮播图:和酷狗音乐的一模一样,在主界面的上方有一个自动循环的轮播图,点击轮播图的每一个图片信息即可进入对应的具体服务,非常具有加分点!

4:音乐唱片的转盘,歌曲同步进度条,以及音乐的暂停/播放/继续/上下歌曲切换!

5:音乐的搜索实现!

6:视频专栏的播放!

7;个人信息界面的布局实现,如反馈,评分,更多,性别年龄昵称,收藏等!

音乐唱片的转盘,歌曲同步进度条,以及音乐的暂停/播放/继续/上下歌曲切换代码如下:

MusicService.java

package com.ypc.xiaoxiongmusic;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import java.util.Timer;
import java.util.TimerTask;
public class MusicService extends Service {
    private MediaPlayer player;
    private Timer timer;//引入⏲
    @Override
    //构造
    public  IBinder onBind(Intent intent){
        return new MusicControl();
    }
    @Override
    public void onCreate(){
        super.onCreate();
        player=new MediaPlayer();//创建音乐播放器对象
    }
    public void addTimer(){ //添加计时器用于设置音乐播放器中的播放进度条
        if(timer==null){
            timer=new Timer();//创建计时器对象
            TimerTask task=new TimerTask() {
                @Override
                public void run() {
                    if (player==null) return;
                    int duration=player.getDuration();//获取歌曲总时长
                    int currentPosition=player.getCurrentPosition();//获取当前播放进度
                    Message msg=Music_Activity.handler.obtainMessage();//创建消息对象
                    //将音乐的总时长和播放进度封装至消息对象中
                    //用getcurrentduration,和getduration获取时间,用bundle封装,handler线程传递
                    Bundle bundle=new Bundle();
                    bundle.putInt("duration",duration);
                    bundle.putInt("currentPosition",currentPosition);
                    msg.setData(bundle);
                    //将消息发送到主线程的消息队列
                    Music_Activity.handler.sendMessage(msg);
                }
            };
            //开始计时任务后的5毫秒,第一次执行task任务,以后每500毫秒执行一次
            timer.schedule(task,5,500);
        }
    }
    class MusicControl extends Binder{//Binder是一种跨进程的通信方式
        public void play(int i){//String path
            Uri uri=null;
            switch(i) {
                case 0:uri = Uri.parse("http://music.163.com/song/media/outer/url?id=5316513.mp3");
                    break;
                case 1:uri = Uri.parse("http://music.163.com/song/media/outer/url?id=409646185.mp3");
                    break;
                case 2:uri= Uri.parse("http://music.163.com/song/media/outer/url?id=26125687.mp3");
                    break;
                case 3:uri = Uri.parse("http://music.163.com/song/media/outer/url?id=516358417.mp3");
                    break;
                case 4: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1492886765.mp3");
                    break;
                case  5: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1436910205.mp3");
                    break;
                case  6: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1399533630.mp3");
                    break;
                case  7: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=32835565.mp3");
                    break;
                case  8: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1422992414.mp3");
                    break;
                case  9: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=29004400.mp3");
                    break;
                case  10: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1439111141.mp3");
                    break;
                case  11: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=29418041.mp3");
                    break;
                case  12: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=472137749.mp3");
                    break;
                case  13: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=507364050.mp3");
                    break;
                case  14: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=426291338.mp3");
                    break;
                case  15: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=34228112.mp3");
                    break;
                case  16: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1428605192.mp3");
                    break;
                case  17: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=33190545.mp3");
                    break;
                case  18: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=32619105.mp3");
                    break;
                case  19: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1425643256.mp3");
                    break;
                case  20: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1305366556.mp3");
                    break;
                case  21: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=481859794.mp3");
                    break;
                case  22: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1424537185.mp3");
                    break;
                case  23: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1403445370.mp3");
                    break;
                case  24: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=36668004.mp3");
                    break;
                case  25: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=548650088.mp3");
                    break;
                case  26: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1409296047.mp3");
                    break;
                case  27: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1389152878.mp3");
                    break;
                case  28: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=475279382.mp3");
                    break;
                case  29: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1464390595.mp3");
                    break;
                case  30: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1464389589.mp3");
                    break;
                case  31: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1464446728.mp3");
                    break;
                case  32: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=1464389585.mp3");
                    break;
                case  33: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=29343374.mp3");
                    break;
                case  34: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=187564.mp3");
                    break;
                case  35: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=26075355.mp3");
                    break;
                case  36: uri = Uri.parse("http://music.163.com/song/media/outer/url?id=187374.mp3");
                    break;
            }
            try {
                player.reset();//重置音乐播放器
                //加载多媒体文件
                player = MediaPlayer.create(getApplicationContext(), uri);
                player.start();//播放音乐
                addTimer();//添加计时器
            } catch (Exception e) {
                e.printStackTrace();
          }
        }

        public boolean pausePlay(){
            player.pause();//暂停播放音乐
            return false;
        }
        public void continuePlay(){
            player.start();//继续播放音乐
        }
        public void seekTo(int progress){
            player.seekTo(progress);//设置音乐的播放位置
        }
    }
    @Override
    public void onDestroy(){
        super.onDestroy();
        if(player==null) return;
        if(player.isPlaying()) player.stop();//停止播放音乐
        player.release();//释放占用的资源
        player=null;//将player置为空
    }
}

Music_Activity.java

扫描二维码关注公众号,回复: 14547075 查看本文章
package com.ypc.xiaoxiongmusic;

import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

import androidx.annotation.RequiresApi;
import static java.lang.Integer.parseInt;
public class Music_Activity extends Activity implements View.OnClickListener{
    private static SeekBar sb;
    private static TextView tv_progress,tv_total;
    private ObjectAnimator animator;//
    private MusicService .MusicControl musicControl;//
    private ImageView bt_1;
    private ImageView iv_music;
    private TextView tv_name;
    private int change;
   String name;
    Intent intent1,intent2;
    MyServiceConn conn;//
   private boolean isUnbind =false;//记录服务是否被解绑
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music);
        intent1=getIntent();
        init();
        View v=findViewById(R.id.bg_1);
       // v.getBackground().setAlpha(180);
        tv_name=findViewById(R.id.song_name);
        iv_music=findViewById(R.id.iv_music);
        bt_1=findViewById(R.id.bt_1);
        bt_1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
    private void init(){
        tv_progress=(TextView)findViewById(R.id.tv_progress);
        tv_total=(TextView)findViewById(R.id.tv_total);
        sb=(SeekBar)findViewById(R.id.sb);
      TextView tv_name=(TextView)findViewById(R.id.song_name);
        ImageView iv_music=(ImageView)findViewById(R.id.iv_music);
        findViewById(R.id.btn_play).setOnClickListener(this);
        findViewById(R.id.btn_pause).setOnClickListener(this);
        findViewById(R.id.btn_continue_play).setOnClickListener(this);
        findViewById(R.id.btn_next).setOnClickListener(this);
        findViewById(R.id.btn_jixu).setOnClickListener(this);
        name=intent1.getStringExtra("name");
        tv_name.setText(name);
        intent2=new Intent(this,MusicService.class);//创建意图对象
        conn=new MyServiceConn();//创建服务连接对象
        bindService(intent2,conn,BIND_AUTO_CREATE);//绑定服务
        //为滑动条添加事件监听
        sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                //进度条改变时,会调用此方法
                if (progress==seekBar.getMax()){//当滑动条到末端时,结束动画
                    animator.pause();//停止播放动画
                }
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {//滑动条开始滑动时调用
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {//滑动条停止滑动时调用
                //根据拖动的进度改变音乐播放进度
                int progress=seekBar.getProgress();//获取seekBar的进度
                musicControl.seekTo(progress);//改变播放进度
            }
        });
        animator= ObjectAnimator.ofFloat(iv_music,"rotation",0f,360.0f);
        animator.setDuration(15000);//动画旋转一周的时间为10秒
        animator.setInterpolator(new LinearInterpolator());//匀速
        animator.setRepeatCount(-1);//-1表示设置动画无限循环
    }

    public static Handler handler=new Handler(){//创建消息处理器对象
        //在主线程中处理从子线程发送过来的消息
        @Override
        public void handleMessage(Message msg){
            Bundle bundle=msg.getData();//获取从子线程发送过来的音乐播放进度
            int duration=bundle.getInt("duration");
            int currentPosition=bundle.getInt("currentPosition");
            sb.setMax(duration);
            sb.setProgress(currentPosition);
            //歌曲总时长
            int minute=duration/1000/60;
            int second=duration/1000%60;
            String strMinute=null;
            String strSecond=null;
            if(minute<10){//如果歌曲的时间中的分钟小于10
                strMinute="0"+minute;//在分钟的前面加一个0
            }else{
                strMinute=minute+"";
            }
            if (second<10){//如果歌曲中的秒钟小于10
                strSecond="0"+second;//在秒钟前面加一个0
            }else{
                strSecond=second+"";
            }
            tv_total.setText(strMinute+":"+strSecond);
            //歌曲当前播放时长
            minute=currentPosition/1000/60;
            second=currentPosition/1000%60;
            if(minute<10){//如果歌曲的时间中的分钟小于10
                strMinute="0"+minute;//在分钟的前面加一个0
            }else{
                strMinute=minute+" ";
            }
            if (second<10){//如果歌曲中的秒钟小于10
                strSecond="0"+second;//在秒钟前面加一个0
            }else{
                strSecond=second+" ";
            }
            tv_progress.setText(strMinute+":"+strSecond);
        }
    };
    class MyServiceConn implements ServiceConnection {//创建一个自定义类用于实现连接服务
        @Override
        public void onServiceConnected(ComponentName name, IBinder service){
            musicControl=(MusicService.MusicControl) service;
        }
        @Override
        public void onServiceDisconnected(ComponentName name){
        }
    }
    private void unbind(boolean isUnbind){
        if(!isUnbind){//判断服务是否被解绑
            musicControl.pausePlay();//暂停播放音乐
            unbindService(conn);//解绑服务
        }
    }
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)//如果注释掉,则需要手动在grideMouble里面把api从15调到更高如19
    @Override
    public void onClick(View v) {
        String position=intent1.getStringExtra("position");
        int i=parseInt(position);
        switch (v.getId()){
            case R.id.btn_play://播放按钮点击事件
                    musicControl.play(i);
                    animator.start();
                break;
            case R.id.btn_pause://暂停按钮点击事件
                musicControl.pausePlay();
                animator.pause();
                break;
            case R.id.btn_jixu://继续按钮点击事件
                musicControl.continuePlay();
                animator.resume();
                break;
            case R.id.btn_continue_play://上一首
                if(( i +change)<1) {
                    change=name.length()-1-i;
                    musicControl.play(i+change);
                    animator.resume();
                    tv_name.setText(name);
                }
                else {
                    change--;
                    musicControl.play(i+change);
                    animator.resume();
                    break;
                }
            case R.id.btn_next://下一首按钮点击事件
                if((i+change)==name.length()-1) {//这里Name.length-1表示的最后一首歌的下标,即歌曲总数-1
                    change=-i;
                    musicControl.play(i+change);
                    iv_music.setImageResource(musicFragment.icons[i+change]);
                   // name_song.setText(name);
                    animator.start();
                    tv_name.setText((String)musicFragment.name[i+change]);
                }
                else {
                    change++;
                    iv_music.setImageResource(musicFragment.icons[i+change]);
                    tv_name.setText(musicFragment.name[i+change]);
                    musicControl.play(i+change);
                    animator.resume();
                    break;
                }
        }
    }
    //不注释,则返回上一界面,会摧毁暂停音乐
/*   @Override
    protected void onDestroy(){
        super.onDestroy();
        unbind(isUnbind);//解绑服务
    }*/
}

activity_music.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"
    tools:context=".Music_Activity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/tpbj"
    android:id="@+id/bg_1">
    <ImageView
        android:src="@drawable/back1"
        android:id="@+id/bt_1"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@drawable/back_layout"
        android:paddingLeft="10dp">
    </ImageView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="-100dp"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/iv_music"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_gravity="center_horizontal"
            android:layout_margin="15dp"
            android:src="@drawable/musicx" />

        <TextView
            android:id="@+id/song_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="歌曲名"
            android:textSize="18sp" />

        <SeekBar
            android:id="@+id/sb"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:paddingLeft="8dp"
            android:paddingRight="8dp">

            <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>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:orientation="horizontal">

            <ImageButton
                android:id="@+id/btn_continue_play"
                android:layout_width="42dp"
                android:layout_height="42dp"
                android:layout_marginTop="8dp"
                android:background="@drawable/music_play"
                android:src="@drawable/xx1" />

            <ImageButton
                android:id="@+id/btn_play"
                android:layout_width="42dp"
                android:layout_height="42dp"
                android:layout_marginLeft="40dp"
                android:layout_marginTop="8dp"
                android:background="@drawable/music_play"
                android:src="@drawable/xx4" />

            <ImageButton
                android:id="@+id/btn_pause"
                android:layout_width="42dp"
                android:layout_height="42dp"
                android:layout_marginLeft="40dp"
                android:layout_marginTop="8dp"
                android:background="@drawable/music_play"
                android:src="@drawable/xx5" />
            <ImageButton
                android:id="@+id/btn_jixu"
                android:layout_width="42dp"
                android:layout_height="42dp"
                android:layout_marginLeft="40dp"
                android:layout_marginTop="8dp"
                android:background="@drawable/music_nextplay"
                android:src="@drawable/xx2" />
            <ImageButton
                android:id="@+id/btn_next"
                android:layout_width="42dp"
                android:layout_height="42dp"
                android:layout_marginLeft="40dp"
                android:layout_marginTop="8dp"
                android:background="@drawable/music_nextplay"
                android:src="@drawable/xx3" />


        </LinearLayout>

    </LinearLayout>
</LinearLayout>

效果截图如下:

猜你喜欢

转载自blog.csdn.net/Abtxr/article/details/126908429