标签:adapter divide 当前时间 apk iap 时长 cursor iss 暂停
本文介绍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"/>
MediaPlayer音乐播放器、上一首、下一首、播放、停止、自动下一首、进度条
标签:adapter divide 当前时间 apk iap 时长 cursor iss 暂停
原文地址:http://www.cnblogs.com/SongYongQian/p/7846233.html