MediaPlayer音乐播放器、上一首、下一首、播放、停止、自动下一首、进度条
本文介绍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音乐播放器、上一首、下一首、播放、停止、自动下一首、进度条相关推荐
- vue 音乐播放器上一首 下一首切换
vue 音乐播放器上一首 下一首切换 根据自定义属性的值找到元素 我是使用监听来实现切换的,将v-for循环列表的index存储在vuex中,点击上一首或下一首改变index的值,在另一个组件中监听i ...
- html音乐唱片自动转,HTML5音乐播放器(四):播放列表与播放方式
发现播放列表和播放方式切换两个功能是连在一起的,单独一个拿出来说不太合适,所以就都一块弄完了.废话不多说,进入主题,功能的逻辑我是这么设计的: 把整个歌曲文件的信息都写在 json 文件里,获取并生成 ...
- HTML5音乐播放器(四):播放列表与播放方式
2019独角兽企业重金招聘Python工程师标准>>> 发现播放列表和播放方式切换两个功能是连在一起的,单独一个拿出来说不太合适,所以就都一块弄完了.废话不多说,进入主题,功能的逻辑 ...
- 删除播放器上的Flowplayer图标
要删除播放器上的Flowplayer图标 ,首先,您需要购买许可证密钥. 许可证密钥对为单个域注册的任意数量的子域有效. 然后只需将播放器的位置更改为flowplayer.commercial-3.2 ...
- 播放器上音频断续问题的原因(realmedia)
[转载]播放器上音频断续问题的原因(realmedia) 这个问题足足花了我三个礼拜.当前产品的播放器在解分辨率高.码率也高的REAL文件时,音频播放一半会断掉,丢掉一小段BUFFER的数据,然后再继 ...
- bal插口_播放器上的这个“昂贵”的插口,是噱头还是真有用
原标题:播放器上的这个"昂贵"的插口,是噱头还是真有用 有不少随身播放器上都有BAL这个插口,只要有这个接口,一般都不会太便宜.但不少朋友却反应听不出平衡口和普通耳机插口(非平衡口 ...
- Beyond Compare 4访问手机或媒体播放器上的文件
Beyond Compare 4 for Windows 可以使用媒体传输协议 (MTP) 访问 Apple iPhone.Android 手机和平板电脑.Windows Phone 设备和某些媒体播 ...
- bal插口_播放器上的“昂贵”插口,是噱头还是真有用
有不少随身播放器上都有 BAL 这个插口,只要有这个接口,一般都不会太便宜.但不少朋友却反应听不出平衡口和普通耳机插口(非平衡口)的区别,认为买上当了. 难道平衡插口只是摆设?乙迷采访到音频品牌乐彼产 ...
- html5的video播放器上禁止下载和禁止右键下载实现。
<video id="video" src="#" controls controlsList="nodownload" oncont ...
- 开发个好的RTMP播放器到底难在哪里?RTMP播放器对标和考察指标
好多开发者提到,RTMP播放器,不知道有哪些对标和考察指标,以下大概聊聊我们的一点经验,感兴趣的,可以关注 github: 1. 低延迟:大多数RTMP的播放都面向直播场景,如果延迟过大,严重影响体验 ...
最新文章
- JavaScript 弱类型
- 二十一、String、StringBuffer和StringBuilder的区别是什么?
- 【原转】使用获取subview获取子view
- ShapeNet:超实时人脸特征点检测与形状拟合开源库
- 当年叱咤风云的框架Struts2,你可知Struts2内功如何修炼之体系结构
- Android Camera之SurfaceView学习
- linux之Fedora 20 开启telnet服务
- ssm基于web的教务管理系统毕业设计源码261620
- <Python启发式自动化>之钉钉推送
- 【存储数据恢复】esx vmfs的互斥导致存储数据丢失的数据恢复案例
- C 语言发展史的点点滴滴
- 高管激励的有效手段----股权激励
- 一年读完100本书(1/100)《微习惯》2021-01-18
- MYSQL学习记录(8)
- narak 靶机实验实战演练
- 数据类型和存储上的差别,基本数据类型,引用数据类型
- 入门Python数据挖掘与机器学习(附代码、实例)
- XAG的真实性以及投资价值
- Java实现堆,最大堆,最小堆,左高树,左低树
- java输出三维数组