音频的播放

在Android中播放音频文件一般都是使用MediaPlayer类来实现的,它对多种格式的音频文件提供了非常全面的控制方法,从而使得播放音乐的工作变得非常简单。

MediaPlayer的生命周期


从上图可以清楚的看出MediaPlayer的工作流程。
首先创建一个MediaPlayer对象,然后调用setDataSource()方法来设置音频播放的路径,再调用prepare()方法使MediaPlayer进行准备状态,接下来调用start()方法就可以开始播放音频,调用pause()方法就可以暂停播放,调用reset()方法就会停止播放。

下面我们写一个简单的音乐播放器,实现一些简单的功能,来深入理解MediaPlayer的用法。

简单的音乐播放器

注意:在我们向模拟器中导入歌曲的时候,不能有中午的歌曲名,否则导入失败!
首先搭建我们的主界面:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><ListView        android:id="@+id/listview"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"></ListView><LinearLayout        android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:orientation="horizontal"><TextView            android:id="@+id/currenttime"android:layout_width="wrap_content"android:layout_height="wrap_content" /><SeekBar            android:id="@+id/seekbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"/><TextView            android:id="@+id/totalttime"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout><LinearLayout        android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#FFFFFF"android:orientation="horizontal"android:gravity="center"><ImageButton            android:id="@+id/last"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@mipmap/before"/><ImageButton            android:id="@+id/play"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/play"/><ImageButton            android:id="@+id/next"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@mipmap/next"/></LinearLayout>
</LinearLayout>

接下来是Drawable文件夹的内容,我们为播放,暂停按钮设置两种不同的转换!
play.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@mipmap/pause" android:state_checked="true"></item><item android:drawable="@mipmap/play"></item>
</selector>

pause.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@mipmap/play" android:state_checked="true"></item><item android:drawable="@mipmap/pause"></item>
</selector>

接下来,为我们的ListView设置布局,展示专辑图片,歌名和歌手名

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"><ImageView        android:id="@+id/imageview"android:layout_width="50dp"android:layout_height="50dp"android:layout_margin="10dp"/><LinearLayout        android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:orientation="vertical"><TextView            android:id="@+id/textview_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="name"/><TextView            android:id="@+id/textview_artist"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="name"/></LinearLayout>
</LinearLayout>

然后为我们的歌曲列表写一个适配器MusicAdapter

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.File;/*** Created by Administrator on 2015/9/10.*/
public class MusicAdapter extends BaseAdapter{private LayoutInflater inflater;private File[] musics;public MusicAdapter(File[] musics, LayoutInflater inflater) {this.musics = musics;this.inflater = inflater;}@Overridepublic int getCount() {return musics.length;}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view;ViewHolder viewHolder;if(convertView==null){view=inflater.inflate(R.layout.musiclist,null);viewHolder=new ViewHolder();viewHolder.imageView= (ImageView) view.findViewById(R.id.imageview);viewHolder.textView_name= (TextView) view.findViewById(R.id.textview_name);viewHolder.textView_artist= (TextView) view.findViewById(R.id.textview_artist);view.setTag(viewHolder);}else{view=convertView;viewHolder= (ViewHolder) view.getTag();}MediaMetadataRetriever mediaMetadataRetriever=new MediaMetadataRetriever();mediaMetadataRetriever.setDataSource(musics[position].getAbsolutePath());byte[] image=mediaMetadataRetriever.getEmbeddedPicture();//得到歌曲的专辑图片if (image!=null){Bitmap bitmap= BitmapFactory.decodeByteArray(image,0,image.length);viewHolder.imageView.setImageBitmap(bitmap);}else {viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);}String artist=mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);//得到歌曲的歌手名if (artist!=null){viewHolder.textView_artist.setText(artist);}else {viewHolder.textView_artist.setText("<未知>");}viewHolder.textView_name.setText(musics[position].getName());//设置歌曲名return view;}class ViewHolder{ImageView imageView;TextView textView_name;TextView textView_artist;}
}

然后定义一个我们自己的常量类Config

/*** Created by Administrator on 2015/9/10.*/
public class Config {public static final int TOTAL_TIME=0;public static final int CURRENT_TIME=1;public static final int START_MUSIC=0;public static final int PAUSE_MUSIC=1;public static final int SEEK_TO=2;public static final String BROADCAST_TAG="com.music.play";public static final String TYPE="type";public static final String TIME="time";public static final String PATH="musicpath";public static final String PROGRESS="progress";
}

接着写一个播放音乐的服务类,所有关于音乐播放的内容都放在这个服务中

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.support.annotation.Nullable;
import java.io.IOException;/*** Created by Administrator on 2015/9/10.*/
public class MusicService extends Service{private MediaPlayer mediaPlayer;@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {int type=intent.getIntExtra(Config.TYPE, 0);switch (type){case Config.START_MUSIC://播放音乐String musicPath=intent.getStringExtra(Config.PATH);if (mediaPlayer==null){mediaPlayer=new MediaPlayer();}mediaPlayer.reset();try {mediaPlayer.setDataSource(musicPath);mediaPlayer.prepare();mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {mp.start();int totalTime=mp.getDuration();//得到总时间Intent intent=new Intent(Config.BROADCAST_TAG);intent.putExtra(Config.TYPE,Config.TOTAL_TIME);intent.putExtra(Config.TIME,totalTime);//将歌曲总时间传回去sendBroadcast(intent);new MusicplayerThread().start();}});} catch (IOException e) {e.printStackTrace();}break;case Config.PAUSE_MUSIC://暂停歌曲if(mediaPlayer.isPlaying()){mediaPlayer.pause();}else {mediaPlayer.start();new MusicplayerThread().start();}break;case Config.SEEK_TO://拖动SeekBar,设置播放进度int progress=intent.getIntExtra(Config.PROGRESS,0);//得到拖动位置mediaPlayer.seekTo(progress);break;default:break;}return super.onStartCommand(intent, flags, startId);}class MusicplayerThread extends Thread{@Overridepublic void run() {while (mediaPlayer.isPlaying()){int currentTime=mediaPlayer.getCurrentPosition();//得到当前播放时间Intent intent=new Intent(Config.BROADCAST_TAG);intent.putExtra(Config.TYPE,Config.CURRENT_TIME);intent.putExtra(Config.TIME,currentTime);//将当前播放时间传回去sendBroadcast(intent);try {Thread.sleep(1000);//休眠,不让消息发送太频繁} catch (InterruptedException e) {e.printStackTrace();}}}}@Overridepublic void onDestroy() {super.onDestroy();if(mediaPlayer!=null){mediaPlayer.stop();mediaPlayer.release();//释放相关资源}}
}

然后不要忘了在applica标签下注册我们的服务

<service android:name=".MusicService"></service>

最后就是我们主活动中的代码:

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.text.SimpleDateFormat;public class MainActivity extends Activity {private MyMusicBroadcastReceicer myMusicBroadcastReceicer;private SeekBar seekBar;private TextView textView_totaltime;private TextView textView_currenttime;private boolean isPlay;private boolean isPause;private boolean isFirstClick = true;private ImageButton button_play;private int listposition;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//File musicFile= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);File file = Environment.getExternalStorageDirectory();File musicFile = new File(file, "/Music");final File[] files = musicFile.listFiles();//得到Music文件夹下所有文件MusicAdapter adapter = new MusicAdapter(files, getLayoutInflater());final ListView listView = (ListView) findViewById(R.id.listview);seekBar = (SeekBar) findViewById(R.id.seekbar);textView_totaltime = (TextView) findViewById(R.id.totalttime);textView_currenttime = (TextView) findViewById(R.id.currenttime);listView.setAdapter(adapter);myMusicBroadcastReceicer = new MyMusicBroadcastReceicer();IntentFilter intentFilter = new IntentFilter(Config.BROADCAST_TAG);registerReceiver(myMusicBroadcastReceicer, intentFilter);//动态注册广播listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//点击ListView播放当前选中歌曲button_play.setBackgroundResource(R.drawable.pause);isFirstClick=false;isPlay=true;isPause=false;listposition=position;//得到当前选中位置Intent intent = new Intent(getApplicationContext(), MusicService.class);intent.putExtra(Config.TYPE, Config.START_MUSIC);intent.putExtra(Config.PATH, files[position].getAbsolutePath());startService(intent);}});seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {Intent intent = new Intent(getApplicationContext(), MusicService.class);intent.putExtra(Config.TYPE, Config.SEEK_TO);intent.putExtra(Config.PROGRESS, seekBar.getProgress());//传回拖动位置startService(intent);}});ImageButton button_last = (ImageButton) findViewById(R.id.last);button_last.setOnClickListener(new View.OnClickListener() {//播放上一首歌@Overridepublic void onClick(View v) {listposition=listposition-1;button_play.setBackgroundResource(R.drawable.pause);isFirstClick=false;isPlay = true;isPause = false;if(listposition>=0){Intent intent = new Intent(getApplicationContext(), MusicService.class);intent.putExtra(Config.TYPE, Config.START_MUSIC);intent.putExtra(Config.PATH, files[listposition].getAbsolutePath());startService(intent);}else {Toast.makeText(getApplicationContext(), "对不起,已经是第一首歌了!", Toast.LENGTH_SHORT).show();listposition=0;}}});button_play = (ImageButton) findViewById(R.id.play);button_play.setOnClickListener(new View.OnClickListener() {//播放歌曲@Overridepublic void onClick(View v) {if (isFirstClick) {//第一次点击播放,默认播放第一首歌button_play.setBackgroundResource(R.drawable.pause);Intent intent = new Intent(getApplicationContext(), MusicService.class);intent.putExtra(Config.TYPE, Config.START_MUSIC);intent.putExtra(Config.PATH, files[0].getAbsolutePath());startService(intent);isFirstClick = false;isPlay = true;isPause = false;} else {if (isPlay) {button_play.setBackgroundResource(R.drawable.play);Intent intent = new Intent(getApplicationContext(), MusicService.class);intent.putExtra(Config.TYPE, Config.PAUSE_MUSIC);startService(intent);isPlay = false;isPause = true;} else if (isPause) {button_play.setBackgroundResource(R.drawable.pause);Intent intent = new Intent(getApplicationContext(), MusicService.class);intent.putExtra(Config.TYPE, Config.PAUSE_MUSIC);startService(intent);isPlay = true;isPause = false;}}}});ImageButton button_next = (ImageButton) findViewById(R.id.next);button_next.setOnClickListener(new View.OnClickListener() {//播放下一首歌@Overridepublic void onClick(View v) {button_play.setBackgroundResource(R.drawable.pause);isFirstClick=false;isPlay = true;isPause = false;listposition=listposition+1;if(listposition<=files.length-1){Intent intent = new Intent(getApplicationContext(), MusicService.class);intent.putExtra(Config.TYPE, Config.START_MUSIC);intent.putExtra(Config.PATH, files[listposition].getAbsolutePath());startService(intent);}else{Toast.makeText(getApplicationContext(), "对不起,已经是最后一首歌了!", Toast.LENGTH_SHORT).show();listposition=files.length-1;}}});}class MyMusicBroadcastReceicer extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {int type = intent.getIntExtra(Config.TYPE, 0);SimpleDateFormat format = new SimpleDateFormat("mm:ss");//设置歌曲显示时间格式switch (type) {case Config.TOTAL_TIME:int totalTime = intent.getIntExtra(Config.TIME, 0);seekBar.setMax(totalTime);textView_totaltime.setText(format.format(totalTime));break;case Config.CURRENT_TIME:int currentTime = intent.getIntExtra(Config.TIME, 0);seekBar.setProgress(currentTime);textView_currenttime.setText(format.format(currentTime));break;default:break;}}}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(myMusicBroadcastReceicer);//将广播解除注册}
}

大功告成!来看一下效果!

这样就实现了播放器的基本功能!

音频的播放、简单音乐播放器相关推荐

  1. input加progress组合写进度条的简单音乐播放器实现

    主要解释一下实现图中的音量进度条效果. 仅供大家参考,勿喷. 查阅了很多资料看了挺多人的代码,但是ajax对于我这个新手小白来说,可能还难以理解,因此分享一个本小白的方法. 本人编程小白,分享实现的方 ...

  2. Android复习02(ListView具体操作[很详细]、简单音乐播放器)

    2020年 3月24日 星期二 Android录播回放 笔记[腾讯课堂] https://ke.qq.com/webcourse/index.html#cid=989760&term_id=1 ...

  3. 安卓java音乐播放器下一曲_Android实现简单音乐播放器(MediaPlayer)

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

  4. iOS之基于FreeStreamer的简单音乐播放器(模仿QQ音乐)

    代码地址如下: http://www.demodashi.com/demo/11944.html 天道酬勤 前言 作为一名iOS开发者,每当使用APP的时候,总难免会情不自禁的去想想,这个怎么做的?该 ...

  5. java计算机毕业设计vue开发一个简单音乐播放器(附源码、数据库)

    java计算机毕业设计vue开发一个简单音乐播放器(附源码.数据库) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Ec ...

  6. 一个简单音乐播放器的java实现(一)

    写在前面 这几天正在读head first系列的书籍,现在正好读的是java.这本书讲的深入浅出,环环相扣,非常精彩,不妨安利给大家,顺便把我学习过程中的一些心得体会已经实例分享出来. 1.一个最简单 ...

  7. 简单音乐播放器html+css+基础vue+含源码,有搜索和播放mv功能,代码可直接复制用。

    题目:html+css+基础vue实现的简单音乐播放器(含源码),有搜索和播放mv功能,代码可直接复制用. 问题描述: 如果vue刚入门,掌握一些基础语法后就可以写一个简单的音乐播放器来练练手~~如果 ...

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

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

  9. C/C++简单音乐播放器系统

    C/C++简单音乐播放器系统 程序设计题 1:简单音乐播放器系统 出题人:吴敏 面向专业:计算机科学与技术 难度等级:4 1 问题描述 编写一个简单音乐播放器软件,实现歌单文件的浏览,点歌,加入收藏夹 ...

  10. C#简单音乐播放器(三)

    简单音乐播放器(三) [上一篇]简单音乐播放器(二) 一.前言 时隔一年,终于回来填坑了.前段时间把这个以前写的东西拿出来大改了UI,然后用去作为数字媒体开发课的作业交了,课上演示效果还不错.因为到了 ...

最新文章

  1. 开源 | IBM、哈佛共同研发:Seq2Seq模型可视化工具
  2. 人脸识别算法初次了解
  3. 什么样的技术人员更容易接到软件开发项目?(论干私活儿)
  4. 设计模式-行为-解释器
  5. 动态规划矩阵连乘问题
  6. SAP WebClient UI view controller所有可用的属性列表
  7. .NET Core 下的爬虫利器
  8. sqlserver 2008安装总是弹出重启提示
  9. word2vec python 代码实现_python gensim使用word2vec词向量处理中文语料的方法
  10. 程序员之常用软件安装过程记录
  11. github使用总结
  12. softmax和cross_entropy
  13. 头文件自包含是什么意思_女朋友发了一张这样的自拍给我,说想我了,她这是什么意思呢?...
  14. c语言启动程序句柄无效,win7系统玩英雄联盟突然弹出“句柄无效”窗口的解决方法...
  15. 详解 0xff 的作用
  16. WWDC 2016 印象初步
  17. {“error“:{“root_cause“:[{“type“:“script_exception“,“reason“:“compile error“,“script_stack“:[“... par
  18. pikachu靶场通关指南
  19. 博途数据类型wstring怎么用_在 STEP 7 (TIA 博途) 中,如何使用用户自定义数据类型 (UDT)?...
  20. 生成树最小树形图 -- 朱刘算法详解

热门文章

  1. 日记侠:朋友圈内容规划5点建议
  2. SolidWorks怎样利用图片快速生成草图——非通用
  3. 关于区块链的一点感悟
  4. Ceph运维存储 命令管理操作
  5. 视频直播技术_直播如何实现低延迟
  6. Docker Engine stopped...
  7. Burpsuit注册机使用时报错java.math.MutableBigInteger.inverseMod64(J)J
  8. PowerDesigner 12中文+破解
  9. 【FXCG】人民币国际支付份额上升
  10. STM32F7系列最小系统原理图