效果图:

在写代码之前,我先告诉你们一个坑点,我在实现这个功能的时候,在导入raw文件时遇到了一个坑,找不到这个文件夹,如果你们也遇到了这种情况,参考我之前写的一篇博客,即可解决问题:https://blog.csdn.net/qq_27494201/article/details/96334284

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button btnStart,btnStop,btnPause,btnReplay;     //  播放器按钮private SeekBar seekBar;                    //  进度条private MediaPlayer mediaPlayer = null;     //  音乐播放控制对象,可以操控暂停、停止、播放、重置等等private Object obj = new Object();      //  对象锁,播放线程暂停时,让进度条线程进入等待状态private Thread seekThread;            //    线程private boolean isRun = false;      //  进度条线程控制private boolean suspended = false;  //  进度条线程等待状态控制@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();     //  初始化控件initJian();     //  添加监听事件seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {              //  进度条的监听事件@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {pause();        //  进度条开始前,调用 pause()}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {              //  进度条开始后,调用 pause()if (mediaPlayer != null && !mediaPlayer.isPlaying()){int progress2 = seekBar.getProgress();int currentPosition2 = mediaPlayer.getDuration()*progress2/100;continuePlay(progress2,currentPosition2);}}});}private void initJian() {btnStart.setOnClickListener(this);btnStop.setOnClickListener(this);btnReplay.setOnClickListener(this);btnPause.setOnClickListener(this);}private void initView() {btnStart = findViewById(R.id.btn_Start);btnStop = findViewById(R.id.btn_Stop);btnPause = findViewById(R.id.btn_Pause);btnReplay = findViewById(R.id.btn_Replay);seekBar = findViewById(R.id.seekBar);}@RequiresApi(api = Build.VERSION_CODES.M)@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.btn_Start:                                //  播放if (mediaPlayer == null){           //  如果没有暂停play();     //  调用 play 方法进行播放}else{if (!mediaPlayer.isPlaying()){             //   如果处于暂停状态int progress = seekBar.getProgress();   //  得到 SeekBar 的进度int currentPosition = mediaPlayer.getCurrentPosition();     //  获取当前位置continuePlay(progress,currentPosition);      //  在从暂停状态恢复播放时使用,除了继续播放音乐,还需要唤醒等待中的进度条绘制线程}}break;case R.id.btn_Pause:                            //  暂停pause();break;case R.id.btn_Replay:                           //  停止if (mediaPlayer == null){          //   播放器对象还未创建或者已经销毁play();}else{if (!mediaPlayer.isPlaying()){      //  暂停状态continuePlay(0,0);      //  进度条为0,第二个参数是:当前播放的位置,因为停止了,所以回到0}else{                     //   正在播放状态不需要唤醒线程的操作,并且这种情况是点了一次停止以后再点停止就会变成播放的作用mediaPlayer.seekTo(0);      //  从0开始播放mediaPlayer.start();                //  开始播放}}break;case R.id.btn_Stop:                             //  重播stop();                 //  这里重播相当于停止break;}}/*  线程用来根据音乐播放进度绘制进度条   */class SeekThread extends  Thread{int duration = mediaPlayer.getDuration();   //当前音乐总长度int currentPosition = 0;public void run(){while (isRun){currentPosition = mediaPlayer.getCurrentPosition(); //  获取当前音乐播放到了哪里seekBar.setProgress(currentPosition*100 / duration);try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}synchronized (obj){while (suspended){try {obj.wait();     //  音乐暂停时让进度条线程也暂停} catch (InterruptedException e) {e.printStackTrace();}}}}}}/*  初始化播放,一个是音乐播放,一个线程控制的进度条绘制  */@RequiresApi(api = Build.VERSION_CODES.M)private void play() {mediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.music_bgw);    //  直接理解为拿到音频资源文件就行mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {    //  监听播放结束事件(停止、暂停、播放完了一首音乐)@Overridepublic void onCompletion(MediaPlayer mp) {if (mediaPlayer != null){           //  如果是暂停的情况stop();             //  调用暂停方法}}});isRun = true;                 //  进度条线程控制,ture为暂停进度条线程的绘制seekThread = new SeekThread();  //  实例化一个线程对象,开始发挥作用mediaPlayer.start();            //  开始播放音乐seekThread.start();             //  启动线程}private void stop() {if (mediaPlayer != null){        //     只要有资源seekBar.setProgress(0);      //     进度条回到0的位置isRun = false;               //     线程mediaPlayer.stop();          //     停止播放音乐mediaPlayer.release();       //     释放资源mediaPlayer = null;          //     销毁音乐对象seekThread = null;           //     销毁线程}}private void pause() {if (mediaPlayer != null && mediaPlayer.isPlaying()){    //  如果音乐对象是有资源 并且 音乐正在播放的状态下mediaPlayer.pause();         //     暂停suspended = true;           //  进度条线程等待状态控制}}//  在从暂停状态恢复播放时使用,除了继续播放音乐,还需要唤醒等待中的进度条绘制线程private void continuePlay(int progress, int currentPosition) {mediaPlayer.seekTo(currentPosition);           //   跳转到对应时间进行播放mediaPlayer.start();                //  开始(暂停也是一种开始,跟播放一样,只是暂停是要回到之前的位置继续播放)seekBar.setProgress(progress);      //  设置回到之前的位置,这个progress是之前播放到的进度!suspended = false;               //  进度条线程等待状态控制synchronized (obj){           //  对象锁,播放线程暂停时,让进度条线程进入等待状态obj.notify();       //  唤醒线程,开始绘制进度条}}}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><SeekBarandroid:id="@+id/seekBar"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="50dp"/><LinearLayoutandroid:id="@+id/ly_main"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="200dp"><Buttonandroid:id="@+id/btn_Start"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:textSize="18dp"android:text="播放"/><Buttonandroid:id="@+id/btn_Stop"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:textSize="18dp"android:text="重播"/><Buttonandroid:id="@+id/btn_Pause"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:textSize="18dp"android:text="暂停"/><Buttonandroid:id="@+id/btn_Replay"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:textSize="18dp"android:text="停止"/></LinearLayout></LinearLayout>

总结:

在本例启动了一个用来绘制进度条的线程 SeekThread,不断获取当前播放的进度,根据进度比例绘制进度条,当音乐播放暂停时,由对象锁 obj 让进度条线程进入等待状态,自爱此播放时唤醒线程,让进度条继续绘制。

如果有问题,可以联系我qq:1787424177

最后,我真诚的希望能评论一句嘛,让我知道你来过,我会很开心的

Android MediaPlayer 实现音乐播放器相关推荐

  1. android音乐播放器案例,Android MediaPlayer实现音乐播放器实例代码

    Android MediaPlayer实现音乐播放器 1.布局文件 android:layout_width="fill_parent" android:layout_height ...

  2. 安卓java自实现mp3播放器,Android MediaPlayer实现音乐播放器实例代码

    Android MediaPlayer实现音乐播放器 1.布局文件 android:layout_width="fill_parent" android:layout_height ...

  3. 基于Android的MediaPlayer的音乐播放器的封装

    基于Android的MediaPlayer的音乐播放器的封装 使用过android原生的mediaplayer来做音频播放的同学们,肯定是经历过一些痛苦的,因为android提供了一个状态机,确实这个 ...

  4. android音乐播放器实现,Android实现简单音乐播放器(MediaPlayer)

    Android实现简单音乐播放器(MediaPlayer),供大家参考,具体内容如下 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 实现一个 ...

  5. Android Studio简易音乐播放器设计作业

    Android Studio简易音乐播放器设计作业 实验成功展示 实验代码 MainActivity.java XML文件 class文件 利用BroadcastReceiver模拟音乐播放器,实现播 ...

  6. Android 简易的音乐播放器

    Android 简易的音乐播放器 效果图: 注备:由于时间问题,歌词未实现. 然后再创建一个raw的文件:如图所示 然后:xml布局为: <?xml version="1.0" ...

  7. [内附完整源码和文档] 基于Android的手机音乐播放器的设计与实现

    摘 要 随着Android系统和移动互联网的快速崛起,手机已经成为人们生活不可缺的一部分,在现代人的生活中,人们生活节奏的加快,生活压力越来越大,碎片化的时间越来越多,那么一个可以在碎片化的时间内调节 ...

  8. 计算机毕业设计android的在线音乐播放器app设计(源码+系统+mysql数据库+Lw文档)

    项目介绍 Android是Google公司公布的基于Linux内核的手机操作系统,其代码属于完全开放,为开源软件开发人员提供使用方便的框架和平台.,本文以Android开发平台为基础,介绍了音乐播放器 ...

  9. 基于android的在线音乐播放器app设计

    Android是Google公司公布的基于Linux内核的手机操作系统,其代码属于完全开放,为开源软件开发人员提供使用方便的框架和平台.,本文以Android开发平台为基础,介绍了音乐播放器的开发.首 ...

  10. Android端本地音乐播放器(一)---前言

    前言: 2018时的记录:大概一周多以前(现在是2018.11.26   15:24)android平台开发的课程结束了,要写大作业,最后决定写这个音乐播放器,因为老师在课堂上讲的例子也是这个,前面的 ...

最新文章

  1. RecyclerView 刷新的时候出现阴影的处理方法
  2. python DBSCAN聚类例子
  3. 支持向量机原理(一)线性支持向量机
  4. 摩托罗拉SE4500 三星 S3C6410 Wince6.0平台软解码调试记录以及驱动相关问题解释
  5. dos一些有意思的命令
  6. C#基础--类/接口/成员修饰符,多态、重载、重写,静态和非静态
  7. 网站运行java_定制化Azure站点Java运行环境(5)
  8. 【01背包】最大约数和(jzoj 2126)
  9. Shell sed命令,替换文件内容、替换目录下所有文件内容、读取文件内容
  10. 一道考查request导致的安全性问题的ctf题
  11. html显示python执行的结果_批量执行用例,且结果显示在html中,python控制台也会显示运行过程...
  12. 用X264编码以后的H264数据
  13. 2021年中国物流科技行业投融资现状及未来发展前景分析[图]
  14. 龚本灿c语言程序设计,c语言程序设计初步-求索学堂.ppt
  15. STM32F103高级定时器死区时间的计算
  16. html预览pdf文件
  17. vmware fusion安装kvm虚拟机
  18. VCSA 6.7.U3n 离线打补丁
  19. PMP项目管理 | 项目质量管理
  20. 面向过程(POP)、面向对象(OOP)、面向接口(IOP)、面向切面(AOP)

热门文章

  1. pku 3592 Instantaneous Transference tarjan缩点重建图+spfa求最长路
  2. 提取身份证信息的自定义函数
  3. GARFIELD@01-04-2005
  4. openmv探索_3_测距以及测量物体大小
  5. git clone指定分支到本地
  6. EMNLP'21 | 检索式对话情感回复
  7. EMNLP'21 | 学习改写非自回归机器翻译的翻译结果
  8. 还在为保研和研究生毕业发愁吗?呐,给你推荐最近的几个保底的会议~
  9. 从三流本科到北京985高校研究生,这是我走过的四年
  10. 【每日算法Day 66】经典面试题:不用四则运算如何做加法?