码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-11-16 22:08:48      阅读:498      评论:0      收藏:0      [点我收藏+]

标签: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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!