Android开发之简易音乐播放器(一)

版权声明:转载请标明链接, https://blog.csdn.net/qq_43433255/article/details/88084420

这里介绍一个简易的音乐播放器,
效果图如下:

但是,由于这是一个简易版的音乐播放器,所播放的音乐只有一首,且被写死,
但,操作却十分简单,方便理解!
这是代码的主要设计:
在这里插入图片描述

音乐主要存放在这一个文件中:
在这里插入图片描述

下面就来介绍各部分代码:
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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#696969">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginTop="10dp"
        android:layout_alignParentTop="true"
        android:id="@+id/title"
        android:orientation="horizontal">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:layout_marginBottom="3dp"
            android:text="生僻字"
            android:textSize="25dp"
            android:gravity="center"
            android:textColor="#ffffff"/>
    </LinearLayout>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="#afafaf"
        android:layout_below="@+id/title"/>
    <ImageView
        android:id="@+id/disc"
        android:layout_width="280dp"
        android:layout_height="280dp"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/title"
        android:layout_marginTop="50dp"
        android:src="@drawable/xcvb" />
    <ImageView
        android:id="@+id/needle"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_below="@+id/title"

        android:layout_marginLeft="150dp"/>

    <RelativeLayout
        android:id="@+id/music1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/rl"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="10dp"
        android:gravity="center">
        <SeekBar
            android:id="@+id/music_seek_bar"
            android:layout_width="240dp"
            android:layout_height="wrap_content"/>
        <TextSwitcher
            android:id="@+id/text_switcher"
            android:layout_width="80dp"
            android:layout_height="50dp"
            android:layout_toRightOf="@+id/music_seek_bar">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="00:00/2:00"
                android:textColor="@color/colorAccent"/>
        </TextSwitcher>
    </RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:gravity="center"
        android:id="@+id/rl"
        android:layout_marginBottom="20dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/playing_pre"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:src="@drawable/music_previous" />

        <ImageView
            android:id="@+id/playing_play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:src="@drawable/music_play" />

        <ImageView
            android:id="@+id/playing_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:src="@drawable/music_next" />
    </LinearLayout>
</RelativeLayout>

main。activity部分:

package com.example.cungu.musicdemo;


import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextSwitcher;

import java.text.SimpleDateFormat;
import java.util.Date;


public class MainActivity extends AppCompatActivity implements View.OnClickListener,
        Runnable, ServiceConnection, SeekBar.OnSeekBarChangeListener {
    private ImageView disc,needle,playingPre,playingPlay,playingNext;
    private ObjectAnimator discAnimation,needleAnimation;//自定义指针和唱盘
    private boolean isPlaying = true;//0,1 判断是否处于播放状态

    //声明服务
    private static final String TAG = MainActivity.class.getSimpleName();
    private MediaService.MusicController mMusicController;
    //使用方法:mMusicController.play();播放   mMusicController.pause();暂停
    private boolean running;
    private TextSwitcher mSwitcher;
    private SeekBar mSeekBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //设置透明栏
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            window.getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            );
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        }
        //滑动条部分
        mSeekBar = (SeekBar) findViewById(R.id.music_seek_bar);
        mSeekBar.setOnSeekBarChangeListener(this);
        mSwitcher = (TextSwitcher) findViewById(R.id.text_switcher);
        mSwitcher.setInAnimation(this, android.R.anim.fade_in);
        mSwitcher.setOutAnimation(this, android.R.anim.fade_out);
        Intent intent = new Intent(this, MediaService.class);
        //增加StartService,来增加后台播放功能
        startService(intent);
        // 绑定服务,使用context来绑定
        // 那个界面需要绑定 就用哪个 Activity
        // 参数1:Intent               代表需要绑定哪一个Service
        // 参数2:ServiceConnection    回调接口,可以接收到Service连接成功和断开的回调,成功就可以取到对象。
        // 绑定服务 参数2就是服务和指定的对象绑定在一起
        bindService(intent, this, BIND_AUTO_CREATE);

        //指针和唱片部分
        initViews();//定义背景图
        setAnimations();
    }
    private void initViews() {
        playingPre = (ImageView) findViewById(R.id.playing_pre);
        playingPlay = (ImageView) findViewById(R.id.playing_play);
        playingNext = (ImageView) findViewById(R.id.playing_next);
        disc = (ImageView) findViewById(R.id.disc);
        needle = (ImageView) findViewById(R.id.needle);
        playingPre.setOnClickListener(this);
        playingPlay.setOnClickListener(this);
        playingNext.setOnClickListener(this);
    }
    //动画设置
    private void setAnimations() {
        discAnimation = ObjectAnimator.ofFloat(disc, "rotation", 0, 360);
        discAnimation.setDuration(20000);
        discAnimation.setInterpolator(new LinearInterpolator());
        discAnimation.setRepeatCount(ValueAnimator.INFINITE);

        needleAnimation = ObjectAnimator.ofFloat(needle, "rotation", 0, 25);
        needle.setPivotX(0);
        needle.setPivotY(0);
        needleAnimation.setDuration(800);
        needleAnimation.setInterpolator(new LinearInterpolator());
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.playing_pre://前一曲
                if (discAnimation != null) {
                    discAnimation.end();
                    playing();
                }
                break;
            case R.id.playing_play://播放中
                if (isPlaying){
                    playing();
                }else {
                    if (needleAnimation != null) {
                        needleAnimation.reverse();
                        needleAnimation.end();
                        mMusicController.pause();
                    }
                    if (discAnimation != null && discAnimation.isRunning()) {
                        discAnimation.cancel();
                        mMusicController.pause();
                        float valueAvatar = (float) discAnimation.getAnimatedValue();
                        discAnimation.setFloatValues(valueAvatar, 360f + valueAvatar);
                    }
                    playingPlay.setImageResource(R.drawable.music_play);
                    isPlaying = true;
                }
                break;
            case R.id.playing_next://下一曲
                if (discAnimation != null) {
                    discAnimation.end();
                    playing();
                }
                break;
            default:
                break;
        }
    }

    //播放:1、播放音乐 2、动画旋转 3、暂停图片切换为播放按钮图片
    private void playing(){
        needleAnimation.start();
        discAnimation.start();
        playingPlay.setImageResource(R.drawable.music_pause);
        mMusicController.play();//播放
        isPlaying = false;
    }
//===================================播放歌曲服务开启、停止、结束===============================
    @Override
    protected void onStart() {
        super.onStart();
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    protected void onStop() {
        running = false;
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        // 解除绑定
        unbindService(this);
        super.onDestroy();
    }

    //---------------------播放到当前音乐的滑动条及时间设置--------------------------
    @Override
    public void run() {
        running = true;
        try {
            while (running) {
                if (mMusicController != null) {
                    long musicDuration = mMusicController.getMusicDuration();
                    final long position = mMusicController.getPosition();
                    final Date dateTotal = new Date(musicDuration);
                    final SimpleDateFormat sb = new SimpleDateFormat("mm:ss");
                    mSeekBar.setMax((int) musicDuration);
                    mSeekBar.setProgress((int) position);
                    mSwitcher.post(
                            new Runnable() {
                                @Override
                                public void run() {
                                    Date date = new Date(position);
                                    String time = sb.format(date) + "/" + sb.format(dateTotal);
                                    mSwitcher.setCurrentText(time);
                                }
                            }
                    );
                }

                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //-----------------------------
    //服务绑定与解除绑定的回调

    /**
     * 当服务与当前绑定对象,绑定成功,服务onBind方法调用并且返回之后
     * 回调给这个方法
     *
     * @param name
     * @param service IBinder 就是服务 onBind 返回的对象
     */
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mMusicController = ((MediaService.MusicController) service);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mMusicController = null;
    }

    public void btnStopService(View view) {
        Intent intent = new Intent(this, MediaService.class);
        stopService(intent);
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        mMusicController.setPosition(seekBar.getProgress());
    }
}

mediaserver部分的代码:

package com.example.cungu.musicdemo;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;


public class MediaService extends Service {
    private MediaPlayer mPlayer;
    /* 绑定服务的实现流程:
     * 1.服务 onCreate, onBind, onDestroy 方法
     * 2.onBind 方法需要返回一个 IBinder 对象
     * 3.如果 Activity 绑定,Activity 就可以取到 IBinder 对象,可以直接调用对象的方法
     */
    // 相同应用内部不同组件绑定,可以使用内部类以及Binder对象来返回。
    public class MusicController extends Binder {
        public void play() {
            mPlayer.start();//开启音乐
        }
        public void pause() {
            mPlayer.pause();//暂停音乐
        }
        public long getMusicDuration() {
            return mPlayer.getDuration();//获取文件的总长度
        }
        public long getPosition() {
            return mPlayer.getCurrentPosition();//获取当前播放进度
        }
        public void setPosition (int position) {
            mPlayer.seekTo(position);//重新设定播放进度
        }
    }
    /**
     * 当绑定服务的时候,自动回调这个方法
     * 返回的对象可以直接操作Service内部的内容
     * @param intent
     * @return
     */
    @Override
    public IBinder onBind(Intent intent) {
        return new MusicController();
    }
    @Override
    public void onCreate() {
        super.onCreate();
        mPlayer = MediaPlayer.create(this, R.raw.yinyue1);
    }
    /**
     * 任意一次unbindService()方法,都会触发这个方法
     * 用于释放一些绑定时使用的资源
     * @param intent
     * @return
     */
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
    @Override
    public void onDestroy() {
        if (mPlayer.isPlaying()) {
            mPlayer.stop();
        }
        mPlayer.release();
        mPlayer = null;
        super.onDestroy();
    }
}



到此,这一个简易的音乐播放器,就完成了。

但是一个音乐播放器,至少播放的音乐不会只有一首,
所以,可以考虑试做一个本地音乐播放器,读取本地的音乐!

猜你喜欢

转载自blog.csdn.net/qq_43433255/article/details/88084420