android 简易音乐播放器(只有核心功能,不花哨)

这是一个超级简单,都是干货的文章

各位同学好,这篇文章的主要知识点在于音频的播放,使用MediaPlayer进行播放音乐,界面以简洁简单为主,废话不多说直接上代码吧。

- 这次由于是本地的文件所以没有权限需要。

  1. 肯定是数据的由来啊
    在这里插入图片描述

  2. Activity 对用的布局文件

<?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="25sp"
            android:gravity="center"
            android:textColor="#ffffff"
            tools:ignore="HardcodedText" />
    </LinearLayout>

    <View
        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="@mipmap/ic_launcher"
        tools:ignore="ContentDescription" />

    <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"
            tools:ignore="RtlHardcoded">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="00:00/2:00"
                android:textColor="@color/colorAccent"
                tools:ignore="HardcodedText" />

        </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">

        <Button
            android:id="@+id/playing_pre"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="上一首"
            tools:ignore="ButtonStyle,HardcodedText" />

        <Button
            android:id="@+id/playing_play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="播放"
            tools:ignore="ButtonStyle,HardcodedText" />

        <Button
            android:id="@+id/playing_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="下一首"
            tools:ignore="ButtonStyle,HardcodedText" />
    </LinearLayout>
</RelativeLayout>

在这里插入图片描述

  1. Activity代码
/**
4. 当前类名 : MusicActivity
5. 包名    : com.jh.music.activitys
7. 类描述  : 简易音乐播放器
8. @author jiahui
*/
public class MusicActivity extends AppCompatActivity implements View.OnClickListener,
       Runnable, ServiceConnection, SeekBar.OnSeekBarChangeListener{
   private ImageView disc;
   private ObjectAnimator discAnimation;//自定义指针和唱盘
   private boolean isPlaying = true;//判断是否处于播放状态

   //声明服务
   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_music);
       //滑动条部分
       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() {
       Button playingPre = (Button) findViewById(R.id.playing_pre);
       Button playingPlay = (Button) findViewById(R.id.playing_play);
       Button playingNext = (Button) findViewById(R.id.playing_next);
       disc = (ImageView) findViewById(R.id.disc);
       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);
   }

   @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 (discAnimation != null && discAnimation.isRunning()) {
                       discAnimation.cancel();
                       mMusicController.pause();
                       float valueAvatar = (float) discAnimation.getAnimatedValue();
                       discAnimation.setFloatValues(valueAvatar, 360f + valueAvatar);
                   }
                   isPlaying = true;
               }
               break;
           case R.id.playing_next://下一曲
               if (discAnimation != null) {
                   discAnimation.end();
                   playing();
               }
               break;
           default:
               break;
       }
   }

   //播放:1、播放音乐 2、动画旋转 3、暂停图片切换为播放按钮图片
   private void playing(){
       discAnimation.start();
       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());
   }
}
  1. Service代码
/**
* 当前类名 : MediaService
* 包名    : com.jh.music.services
* 类描述  : 播放音乐的Service
* @author jiahui
*/
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内部的内容
    */
   @Override
   public IBinder onBind(Intent intent) {
       return new MusicController();
   }
   @Override
   public void onCreate() {
       super.onCreate();
       mPlayer = MediaPlayer.create(this, R.raw.music_rose);
   }
   /**
    * 任意一次unbindService()方法,都会触发这个方法
    * 用于释放一些绑定时使用的资源
    */
   @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();
   }

}

按照我的顺序往项目中拷贝就可以运行,运行不起来找我,ok到此结束,通篇没有废话,因为我在代码中都添加了注释,对了文章尾部要提供Api,不好意思差点忘了,运行效果就不加了,跟布局相同

MediaPlayer 常用方法介绍
 方法:create(Context context, Uri uri)
解释:静态方法,通过Uri创建一个多媒体播放器。
方法:create(Context context, int resid)
解释:静态方法,通过资源ID创建一个多媒体播放器
方法:create(Context context, Uri uri, SurfaceHolder holder)
解释:静态方法,通过Uri和指定 SurfaceHolder 【抽象类】 创建一个多媒体播放器
方法: getCurrentPosition()
解释:返回 Int, 得到当前播放位置
方法: getDuration()
解释:返回 Int,得到文件的时间
方法:getVideoHeight()
解释:返回 Int ,得到视频的高度
方法:getVideoWidth()
解释:返回 Int,得到视频的宽度
方法:isLooping()
解释:返回 boolean ,是否循环播放
方法:isPlaying()
解释:返回 boolean,是否正在播放
方法:pause()
解释:无返回值 ,暂停
方法:prepare()
解释:无返回值,准备同步
方法:prepareAsync()
解释:无返回值,准备异步
方法:release()
解释:无返回值,释放 MediaPlayer  对象
方法:reset()
解释:无返回值,重置 MediaPlayer  对象
方法:seekTo(int msec)
解释:无返回值,指定播放的位置(以毫秒为单位的时间)
方法:setAudioStreamType(int streamtype)
解释:无返回值,指定流媒体的类型
方法:setDataSource(String path)
解释:无返回值,设置多媒体数据来源【根据 路径】
方法:setDataSource(FileDescriptor fd, long offset, long length)
解释:无返回值,设置多媒体数据来源【根据 FileDescriptor】
方法:setDataSource(FileDescriptor fd)
解释:无返回值,设置多媒体数据来源【根据 FileDescriptor】
方法:setDataSource(Context context, Uri uri)
解释:无返回值,设置多媒体数据来源【根据 Uri】
方法:setDisplay(SurfaceHolder sh)
解释:无返回值,设置用 SurfaceHolder 来显示多媒体
方法:setLooping(boolean looping)
解释:无返回值,设置是否循环播放
事件:setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener)
解释:监听事件,网络流媒体的缓冲监听
事件:setOnCompletionListener(MediaPlayer.OnCompletionListener listener)
解释:监听事件,网络流媒体播放结束监听
事件:setOnErrorListener(MediaPlayer.OnErrorListener listener)
解释:监听事件,设置错误信息监听
事件:setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener)
解释:监听事件,视频尺寸监听
方法:setScreenOnWhilePlaying(boolean screenOn)
解释:无返回值,设置是否使用 SurfaceHolder 显示
方法:setVolume(float leftVolume, float rightVolume)
解释:无返回值,设置音量
方法:start()
解释:无返回值,开始播放
方法:stop()
解释:无返回值,停止播放
  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值