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"/> 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM