本文介绍MediaPlayer的使用。MediaPlayer可以播放音频和视频,另外也可以通过VideoView来播放视频,虽然VideoView比MediaPlayer简单易用,但定制性不如用MediaPlayer,要视情况选择了。MediaPlayer播放音频比较简单,但是要播放视频就需要SurfaceView。SurfaceView比普通的自定义View更有绘图上的优势,它支持完全的OpenGL ES库。

先贴出本文程序运行结果的截图,下面是上一首、下一首、播放、停止、自动下一首、可用SeekBar来调进度:

布局文件:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout
 3     xmlns:android="http://schemas.android.com/apk/res/android"
 4     xmlns:app="http://schemas.android.com/apk/res-auto"
 5     xmlns:tools="http://schemas.android.com/tools"
 6     android:layout_width="match_parent"
 7     android:layout_height="match_parent"
 8     android:orientation="vertical"
 9     tools:context="net.bwie.mediaplayer.MainActivity">
10
11     <RelativeLayout
12         android:layout_width="match_parent"
13         android:layout_height="wrap_content">
14
15         <TextView
16             android:id="@+id/current_time_tv"
17             android:layout_width="wrap_content"
18             android:layout_height="wrap_content"
19             android:text="当前时间"/>
20
21         <TextView
22             android:id="@+id/total_time_tv"
23             android:layout_width="wrap_content"
24             android:layout_height="wrap_content"
25             android:layout_alignParentRight="true"
26             android:text="全部时间"/>
27
28         <SeekBar
29             android:id="@+id/seek_bar"
30             style="?android:progressBarStyleHorizontal"
31             android:layout_width="match_parent"
32             android:layout_height="50dp"
33             android:layout_toLeftOf="@id/total_time_tv"
34             android:layout_toRightOf="@id/current_time_tv"/>
35
36     </RelativeLayout>
37
38     <LinearLayout
39         android:layout_width="match_parent"
40         android:layout_height="wrap_content">
41
42         <Button
43             android:id="@+id/previous_btn"
44             android:layout_width="0dp"
45             android:layout_height="wrap_content"
46             android:layout_weight="1"
47             android:text="上一曲"/>
48
49         <Button
50             android:id="@+id/play_btn"
51             android:layout_width="0dp"
52             android:layout_height="wrap_content"
53             android:layout_weight="1"
54             android:text="播放/暂停"/>
55
56         <Button
57             android:id="@+id/next_btn"
58             android:layout_width="0dp"
59             android:layout_height="wrap_content"
60             android:layout_weight="1"
61             android:text="下一曲"/>
62
63     </LinearLayout>
64
65
66     <ListView
67         android:id="@+id/list_view"
68         android:layout_width="match_parent"
69         android:layout_height="match_parent"
70         android:divider="#f00"
71         android:dividerHeight="2dp"/>
72
73 </LinearLayout>

Bean类:

 1 package net.bwie.mediaplayer.bean;
 2
 3 public class MediaInfo {
 4
 5     private long _id;
 6     private String uri;// 路径
 7     private String title;
 8     private String artist;// 艺术家
 9
10     public MediaInfo(long _id, String uri, String title, String artist) {
11         this._id = _id;
12         this.uri = uri;
13         this.title = title;
14         this.artist = artist;
15     }
16
17     public long get_id() {
18         return _id;
19     }
20
21     public void set_id(long _id) {
22         this._id = _id;
23     }
24
25     public String getUri() {
26         return uri;
27     }
28
29     public void setUri(String uri) {
30         this.uri = uri;
31     }
32
33     public String getTitle() {
34         return title;
35     }
36
37     public void setTitle(String title) {
38         this.title = title;
39     }
40
41     public String getArtist() {
42         return artist;
43     }
44
45     public void setArtist(String artist) {
46         this.artist = artist;
47     }
48
49     @Override
50     public String toString() {
51         return "MediaInfo{" +
52                 "_id=" + _id +
53                 ", uri='" + uri + '\'' +
54                 ", title='" + title + '\'' +
55                 ", artist='" + artist + '\'' +
56                 '}';
57     }
58 }

Activity主页面:

  1 /**
  2  * 1、查询全部歌曲信息并展示(ContentProvider数据库)
  3  * 2、点击对应歌曲播放/暂停
  4  * 3、播放/暂停按钮。上一首/下一首
  5  * 注意:设置外部存储权限
  6  * build.gradle中targetSdkVersion 22
  7  * <p>
  8  * 进度条部分
  9  * 1、进度条跟随歌曲进度而变化
 10  * 实现周期性改变进度条位置:1、Handler,2、TimerTask定时器
 11  * 2、拖动进度条让MediaPlayer播放对应位置的声音
 12  * SeekBar绑定监听器
 13  * MediaPlayer绑定播放完毕监听器,实现自动播放下一曲
 14  */
 15 public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, View.OnClickListener, SeekBar.OnSeekBarChangeListener, MediaPlayer.OnCompletionListener {
 16
 17     protected ListView mListView;
 18     protected Button mPreviousBtn;
 19     protected Button mPlayBtn;
 20     protected Button mNextBtn;
 21     protected TextView mCurrentTimeTv;
 22     protected TextView mTotalTimeTv;
 23     protected SeekBar mSeekBar;
 24     private List<MediaInfo> mMediaInfoList;
 25
 26     private MediaPlayer mMediaPlayer;
 27
 28     // 记录当前播放歌曲的位置
 29     private int mCurrentPosition;
 30
 31     private Handler mHandler = new Handler(new Handler.Callback() {
 32         @Override
 33         public boolean handleMessage(Message msg) {
 34
 35             // 展示给进度条和当前时间
 36             int progress = mMediaPlayer.getCurrentPosition();
 37             mSeekBar.setProgress(progress);
 38             mCurrentTimeTv.setText(parseTime(progress));
 39
 40             // 继续定时发送数据
 41             updateProgress();
 42
 43             return true;
 44         }
 45     });
 46
 47     @Override
 48     protected void onCreate(Bundle savedInstanceState) {
 49         super.onCreate(savedInstanceState);
 50         super.setContentView(R.layout.activity_main);
 51         initView();
 52
 53         mMediaInfoList = getDatas();
 54
 55         ArrayAdapter adapter = new ArrayAdapter(this,
 56                 android.R.layout.simple_list_item_1,
 57                 mMediaInfoList);
 58
 59         mListView.setAdapter(adapter);
 60         mListView.setOnItemClickListener(this);
 61     }
 62
 63     private void initView() {
 64         mListView = (ListView) findViewById(R.id.list_view);
 65         mPreviousBtn = (Button) findViewById(R.id.previous_btn);
 66         mPreviousBtn.setOnClickListener(MainActivity.this);
 67         mPlayBtn = (Button) findViewById(R.id.play_btn);
 68         mPlayBtn.setOnClickListener(MainActivity.this);
 69         mNextBtn = (Button) findViewById(R.id.next_btn);
 70         mNextBtn.setOnClickListener(MainActivity.this);
 71         mCurrentTimeTv = (TextView) findViewById(R.id.current_time_tv);
 72         mTotalTimeTv = (TextView) findViewById(R.id.total_time_tv);
 73         mSeekBar = (SeekBar) findViewById(R.id.seek_bar);
 74
 75         // SeekBar绑定监听器,监听拖动到指定位置
 76         mSeekBar.setOnSeekBarChangeListener(this);
 77
 78     }
 79
 80     // 获取系统媒体数据库中的音频多媒体信息
 81     private List<MediaInfo> getDatas() {
 82         List<MediaInfo> list = new ArrayList<>();
 83
 84         // 使用内容解析者访问系统提供的数据库
 85         Cursor cursor = getContentResolver()
 86                 .query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
 87                         null,
 88                         null,
 89                         null,
 90                         MediaStore.Audio.Media.DEFAULT_SORT_ORDER);// 默认排序顺序
 91         // 如果游标读取时还有下一个数据,读取
 92
 93         int idIndex = cursor.getColumnIndex(MediaStore.Audio.Media._ID);//获取列名对应的索引
 94         int titleIndex = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);// 标题
 95         int artistIndex = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);// 艺术家
 96         int uriIndex = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);// 文件路径
 97         while (cursor.moveToNext()) {
 98             // 根据索引值获取对应列名中的数值
 99             long _id = cursor.getLong(idIndex);
100             String title = cursor.getString(titleIndex);
101             String artist = cursor.getString(artistIndex);
102             String uri = cursor.getString(uriIndex);
103
104             MediaInfo mediaInfo = new MediaInfo(_id, uri, title, artist);
105
106             list.add(mediaInfo);
107         }
108
109         for (MediaInfo mediaInfo : list) {
110             Log.d("1507", "" + mediaInfo.toString());
111         }
112         return list;
113     }
114
115     @Override
116     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
117         mCurrentPosition = position;
118
119         changeMusic(mCurrentPosition);
120     }
121
122     @Override
123     public void onClick(View view) {
124
125         if (view.getId() == R.id.previous_btn) {// 上一首
126             changeMusic(--mCurrentPosition);
127         } else if (view.getId() == R.id.play_btn) {// 播放/暂停
128
129             // 首次点击播放按钮,默认播放第0首
130             if (mMediaPlayer == null) {
131                 changeMusic(0);
132             } else {
133                 playOrPause();
134             }
135
136         } else if (view.getId() == R.id.next_btn) {// 下一首
137             changeMusic(++mCurrentPosition);
138         }
139
140     }
141
142     // 播放或暂停
143     private void playOrPause() {
144         if (mMediaPlayer.isPlaying()) {
145             mMediaPlayer.pause();
146         } else {
147             mMediaPlayer.start();
148         }
149     }
150
151     // 基本数据类型和String在方法调用中传递的是值
152     // 其他数据类型在方法调用中传递的是引用
153
154     // 切歌
155     private void changeMusic(int position) {
156         if (position < 0) {
157             mCurrentPosition = position = mMediaInfoList.size() - 1;
158         } else if (position > mMediaInfoList.size() - 1) {
159             mCurrentPosition = position = 0;
160         }
161
162         if (mMediaPlayer == null) {
163             mMediaPlayer = new MediaPlayer();
164             // 绑定播放完毕监听器
165             mMediaPlayer.setOnCompletionListener(this);
166         }
167
168         try {
169             // 切歌之前先重置,释放掉之前的资源
170             mMediaPlayer.reset();
171             // 设置播放源
172             mMediaPlayer.setDataSource(mMediaInfoList.get(position).getUri());
173             // 开始播放前的准备工作,加载多媒体资源,获取相关信息
174             mMediaPlayer.prepare();
175             // 开始播放
176             mMediaPlayer.start();
177         } catch (IOException e) {
178             e.printStackTrace();
179             Toast.makeText(this, "播放错误", Toast.LENGTH_SHORT).show();
180         }
181
182         // 切歌时重置进度条并展示歌曲时长
183         mSeekBar.setProgress(0);
184         mSeekBar.setMax(mMediaPlayer.getDuration());
185         mTotalTimeTv.setText(parseTime(mMediaPlayer.getDuration()));
186
187         updateProgress();
188     }
189
190     // 每间隔1s通知更新进度
191     private void updateProgress() {
192         // 使用Handler每间隔1s发送一次空消息,通知进度条更新
193         Message msg = Message.obtain();// 获取一个现成的消息
194         mHandler.sendMessageDelayed(msg, INTERNAL_TIME);
195     }
196
197     // 解析时间
198     private String parseTime(int oldTime) {
199         SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");// 时间格式
200         String newTime = sdf.format(new Date(oldTime));
201         return newTime;
202     }
203
204     private static final int INTERNAL_TIME = 1000;// 音乐进度间隔时间
205
206     @Override
207     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
208
209     }
210
211     @Override
212     public void onStartTrackingTouch(SeekBar seekBar) {
213
214     }
215
216     // 当手停止拖拽进度条时执行该方法
217     // 获取拖拽进度
218     // 将进度对应设置给MediaPlayer
219     @Override
220     public void onStopTrackingTouch(SeekBar seekBar) {
221         int progress = seekBar.getProgress();
222         mMediaPlayer.seekTo(progress);
223     }
224
225     @Override
226     public void onCompletion(MediaPlayer mp) {
227         // 当歌曲播放完毕,切歌到下一首
228         changeMusic(++mCurrentPosition);
229     }
230 }

权限:

 1 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

转载于:https://www.cnblogs.com/SongYongQian/p/7846233.html

MediaPlayer音乐播放器、上一首、下一首、播放、停止、自动下一首、进度条相关推荐

  1. vue 音乐播放器上一首 下一首切换

    vue 音乐播放器上一首 下一首切换 根据自定义属性的值找到元素 我是使用监听来实现切换的,将v-for循环列表的index存储在vuex中,点击上一首或下一首改变index的值,在另一个组件中监听i ...

  2. html音乐唱片自动转,HTML5音乐播放器(四):播放列表与播放方式

    发现播放列表和播放方式切换两个功能是连在一起的,单独一个拿出来说不太合适,所以就都一块弄完了.废话不多说,进入主题,功能的逻辑我是这么设计的: 把整个歌曲文件的信息都写在 json 文件里,获取并生成 ...

  3. HTML5音乐播放器(四):播放列表与播放方式

    2019独角兽企业重金招聘Python工程师标准>>> 发现播放列表和播放方式切换两个功能是连在一起的,单独一个拿出来说不太合适,所以就都一块弄完了.废话不多说,进入主题,功能的逻辑 ...

  4. 删除播放器上的Flowplayer图标

    要删除播放器上的Flowplayer图标 ,首先,您需要购买许可证密钥. 许可证密钥对为单个域注册的任意数量的子域有效. 然后只需将播放器的位置更改为flowplayer.commercial-3.2 ...

  5. 播放器上音频断续问题的原因(realmedia)

    [转载]播放器上音频断续问题的原因(realmedia) 这个问题足足花了我三个礼拜.当前产品的播放器在解分辨率高.码率也高的REAL文件时,音频播放一半会断掉,丢掉一小段BUFFER的数据,然后再继 ...

  6. bal插口_播放器上的这个“昂贵”的插口,是噱头还是真有用

    原标题:播放器上的这个"昂贵"的插口,是噱头还是真有用 有不少随身播放器上都有BAL这个插口,只要有这个接口,一般都不会太便宜.但不少朋友却反应听不出平衡口和普通耳机插口(非平衡口 ...

  7. Beyond Compare 4访问手机或媒体播放器上的文件

    Beyond Compare 4 for Windows 可以使用媒体传输协议 (MTP) 访问 Apple iPhone.Android 手机和平板电脑.Windows Phone 设备和某些媒体播 ...

  8. bal插口_播放器上的“昂贵”插口,是噱头还是真有用

    有不少随身播放器上都有 BAL 这个插口,只要有这个接口,一般都不会太便宜.但不少朋友却反应听不出平衡口和普通耳机插口(非平衡口)的区别,认为买上当了. 难道平衡插口只是摆设?乙迷采访到音频品牌乐彼产 ...

  9. html5的video播放器上禁止下载和禁止右键下载实现。

    <video id="video" src="#" controls controlsList="nodownload" oncont ...

  10. 开发个好的RTMP播放器到底难在哪里?RTMP播放器对标和考察指标

    好多开发者提到,RTMP播放器,不知道有哪些对标和考察指标,以下大概聊聊我们的一点经验,感兴趣的,可以关注 github: 1. 低延迟:大多数RTMP的播放都面向直播场景,如果延迟过大,严重影响体验 ...

最新文章

  1. JavaScript 弱类型
  2. 二十一、String、StringBuffer和StringBuilder的区别是什么?
  3. 【原转】使用获取subview获取子view
  4. ShapeNet:超实时人脸特征点检测与形状拟合开源库
  5. 当年叱咤风云的框架Struts2,你可知Struts2内功如何修炼之体系结构
  6. Android Camera之SurfaceView学习
  7. linux之Fedora 20 开启telnet服务
  8. ssm基于web的教务管理系统毕业设计源码261620
  9. <Python启发式自动化>之钉钉推送
  10. 【存储数据恢复】esx vmfs的互斥导致存储数据丢失的数据恢复案例
  11. C 语言发展史的点点滴滴
  12. 高管激励的有效手段----股权激励
  13. 一年读完100本书(1/100)《微习惯》2021-01-18
  14. MYSQL学习记录(8)
  15. narak 靶机实验实战演练
  16. 数据类型和存储上的差别,基本数据类型,引用数据类型
  17. 入门Python数据挖掘与机器学习(附代码、实例)
  18. XAG的真实性以及投资价值
  19. Java实现堆,最大堆,最小堆,左高树,左低树
  20. java输出三维数组

热门文章

  1. 微信公众平台开发 数据库操作
  2. Westcar液力耦合器易熔塞-WESTCAR限矩型液力偶合器的过载保护装置
  3. 面试奇淫巧技之——STAR法则+BEI面试大法
  4. 专访王志海:棱镜门后企业数据安全之恙
  5. DEJA_VU3D - Cesium功能集 之 079-对象材质:动态扩散圆
  6. Oracle 实例管理
  7. 多种方式实现web端截屏录屏
  8. Linux文件的压缩和解压命令tar
  9. 虚拟内存和物理内存的直观理解(概念、区别与联系)
  10. 日均访问量过万的网站一般需要多大的云服务器