简单的音乐播放器(上一曲,下一曲,暂停/播放,自动播放下一曲)
public class MainActivity extends AppCompatActivity implements View.OnClickListener, SeekBar.OnSeekBarChangeListener, MediaPlayer.OnCompletionListener { private MediaPlayer mediaPlayer;//播放音频的 private Button mPreviousBtn; private Button mPlayBtn; private Button mNextBtn; private ListView mListView; private List<Song> list; private MyAdapter adapter; private SeekBar mSeekBar; private TextView mCurrentTimeTv; private TextView mTotalTimeTv; // 记录当前播放歌曲的位置 private int mCurrentPosition; private Handler mHandler=new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message message) { // 展示给进度条和当前时间 int progress = mediaPlayer.getCurrentPosition(); mSeekBar.setProgress(progress); mCurrentTimeTv.setText(parseTime(progress)); // 继续定时发送数据 updateProgress(); return true; } }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mediaPlayer = new MediaPlayer(); mPreviousBtn= (Button) findViewById(R.id.mPreviousBtn); mPlayBtn= (Button) findViewById(R.id.mPlayBtn); mNextBtn= (Button) findViewById(R.id.mNextBtn); mCurrentTimeTv= (TextView) findViewById(R.id.current_time_tv); mTotalTimeTv= (TextView) findViewById(R.id.total_time_tv); mSeekBar= (SeekBar) findViewById(R.id.seek_bar); mSeekBar.setOnSeekBarChangeListener(this); mPreviousBtn.setOnClickListener(this); mPlayBtn.setOnClickListener(this); mNextBtn.setOnClickListener(this); initView(); } /** * 初始化view */ private void initView() { mListView = (ListView) findViewById(R.id.main_listview); list = new ArrayList<>(); //把扫描到的音乐赋值给list list = MusicUtils.getMusicData(this); adapter = new MyAdapter(this,list); mListView.setAdapter(adapter); mediaPlayer.setOnCompletionListener(this); mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { //创建一个播放音频的方法,把点击到的地址传过去 //list.get(i).path这个就是歌曲的地址 // String path = list.get(i).path; // Log.i("WDD",path); mCurrentPosition=i; changeMusic(mCurrentPosition); // play(list.get(i).path); // String singer = list.get(i).singer;//歌手 // String song = list.get(i).song;//歌曲名称 // int duration = list.get(i).duration;//歌曲长度 // String time = MusicUtils.formatTime(duration); // String s=singer+"\n"+song+"\n"+time; // AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this); // builder.setTitle("歌曲"); // builder.setMessage(s); // builder.show(); } }); } // /** // * 播放音频的方法 // */ // private void play(String path) { // //播放之前要先把音频文件重置 // try { // mediaPlayer.reset(); // //调用方法传进去要播放的音频路径 // mediaPlayer.setDataSource(path); // //异步准备音频资源 // mediaPlayer.prepareAsync(); // //调用mediaPlayer的监听方法,音频准备完毕会响应此方法 // mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { // @Override // public void onPrepared(MediaPlayer mediaPlayer) { // mediaPlayer.start();//开始音频 // } // }); // } catch (IOException e) { // e.printStackTrace(); // } // } @Override public void onClick(View view) { if (view.getId()==R.id.mPreviousBtn){//上一曲 changeMusic(--mCurrentPosition); }else if (view.getId()==R.id.mPlayBtn){//暂停/播放 // 首次点击播放按钮,默认播放第0首 if (mediaPlayer==null){ changeMusic(0); }else { if (mediaPlayer.isPlaying()){ mediaPlayer.pause(); }else { mediaPlayer.start(); } } }else if (view.getId()==R.id.mNextBtn){// 下一首 changeMusic(++mCurrentPosition); } } // 基本数据类型和String在方法调用中传递的是值 // 其他数据类型在方法调用中传递的是引用 //切歌 private void changeMusic(int position){ if (position<0){ mCurrentPosition = position =list.size()-1; }else if (position>list.size()-1){ mCurrentPosition = position=0; } if (mediaPlayer==null){ mediaPlayer=new MediaPlayer(); } try { // 切歌之前先重置,释放掉之前的资源 mediaPlayer.reset(); // 设置播放源 mediaPlayer.setDataSource(list.get(position).path); // 开始播放前的准备工作,加载多媒体资源,获取相关信息 mediaPlayer.prepare(); // 开始播放 mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } // 切歌时重置进度条并展示歌曲时长 mSeekBar.setProgress(0); mSeekBar.setMax(mediaPlayer.getDuration()); mTotalTimeTv.setText(parseTime(mediaPlayer.getDuration())); updateProgress(); } private void updateProgress() { // 使用Handler每间隔1s发送一次空消息,通知进度条更新 Message msg = Message.obtain();// 获取一个现成的消息 // 使用MediaPlayer获取当前播放时间除以总时间的进度 int progress = mediaPlayer.getCurrentPosition(); msg.arg1 = progress; mHandler.sendMessageDelayed(msg, INTERNAL_TIME); } private String parseTime(int oldTime) { SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");// 时间格式 String newTime = sdf.format(new Date(oldTime)); return newTime; } private static final int INTERNAL_TIME = 1000;// 音乐进度间隔时间 @Override public void onProgressChanged(SeekBar seekBar, int i, boolean b) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } // 当手停止拖拽进度条时执行该方法 // 获取拖拽进度 // 将进度对应设置给MediaPlayer @Override public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekBar.getProgress(); mediaPlayer.seekTo(progress); } @Override public void onCompletion(MediaPlayer mediaPlayer) { changeMusic(++mCurrentPosition); } }
** * 音乐工具类, */ public class MusicUtils { /** * 扫描系统里面的音频文件,返回一个list集合 */ public static List<Song> getMusicData(Context context) { List<Song> list = new ArrayList<Song>(); // 媒体库查询语句(写一个工具类MusicUtils) Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.AudioColumns.IS_MUSIC); if (cursor != null) { while (cursor.moveToNext()) { Song song = new Song(); song.song = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)); song.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)); song.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); song.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)); song.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)); if (song.size > 1000 * 800) { // 注释部分是切割标题,分离出歌曲名和歌手 (本地媒体库读取的歌曲信息不规范) if (song.song.contains("-")) { String[] str = song.song.split("-"); song.singer = str[0]; song.song = str[1]; } list.add(song); } } // 释放资源 cursor.close(); } return list; } /** * 定义一个方法用来格式化获取到的时间 */ public static String formatTime(int time) { if (time / 1000 % 60 < 10) { return time / 1000 / 60 + ":0" + time / 1000 % 60; } else { return time / 1000 / 60 + ":" + time / 1000 % 60; } } }
package com.example.lenovo.yinyuekao2; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.List; public class MyAdapter extends BaseAdapter { private Context context; private List<Song> list; public MyAdapter(MainActivity mainActivity, List<Song> list) { this.context = mainActivity; this.list = list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int i) { return list.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(final int i, View view, ViewGroup viewGroup) { ViewHolder holder = null; if (view == null) { holder = new ViewHolder(); //引入布局 view = View.inflate(context, R.layout.item_music_listview, null); //实例化对象 holder.song = (TextView) view.findViewById(R.id.item_mymusic_song); holder.singer = (TextView) view.findViewById(R.id.item_mymusic_singer); holder.duration = (TextView) view.findViewById(R.id.item_mymusic_duration); holder.position = (TextView) view.findViewById(R.id.item_mymusic_postion); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } //给控件赋值 holder.song.setText(list.get(i).song.toString()); holder.singer.setText(list.get(i).singer.toString()); //时间需要转换一下 int duration = list.get(i).duration; String time = MusicUtils.formatTime(duration); holder.duration.setText(time); holder.position.setText(i+1+""); return view; } class ViewHolder{ TextView song;//歌曲名 TextView singer;//歌手 TextView duration;//时长 TextView position;//序号 String parh;//地址 } }
package com.example.lenovo.yinyuekao2; /** * Created by LENOVO on 2017/11/7. */ /** * Created by user on 2016/6/24. * 放置音乐 */ public class Song { /** * 歌手 */ public String singer; /** * 歌曲名 */ public String song; /** * 歌曲的地址 */ public String path; /** * 歌曲长度 */ public int duration; /** * 歌曲的大小 */ public long size; }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.lenovo.yinyuekao2.MainActivity"> <LinearLayout android:orientation="horizontal" android:id="@+id/main_textview" android:layout_width="match_parent" android:layout_height="40dp"> <Button android:id="@+id/mPreviousBtn" android:text="上一曲" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" /> <Button android:id="@+id/mPlayBtn" android:text="播放/暂停" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" /> <Button android:id="@+id/mNextBtn" android:text="下一曲" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" /> </LinearLayout> <RelativeLayout android:id="@+id/main_textview1" android:layout_below="@+id/main_textview" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/current_time_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="当前时间"/> <TextView android:id="@+id/total_time_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="全部时间"/> <SeekBar android:id="@+id/seek_bar" style="?android:progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="50dp" android:layout_toLeftOf="@id/total_time_tv" android:layout_toRightOf="@id/current_time_tv"/> </RelativeLayout> <ListView android:id="@+id/main_listview" android:layout_below="@+id/main_textview1" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="110dp" android:orientation="horizontal" android:gravity="center_vertical" android:padding="5dp"> <TextView android:id="@+id/item_mymusic_postion" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="1" android:gravity="center" android:textColor="#0d0c0c" android:textSize="18sp" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" > <TextView android:id="@+id/item_mymusic_song" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="歌曲名" android:textColor="#0d0c0c" android:textSize="20dp" /> <TextView android:id="@+id/item_mymusic_singer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/item_mymusic_song" android:text="歌手" android:textColor="#0d0c0c" android:textSize="15sp" /> <TextView android:id="@+id/item_mymusic_duration" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/item_mymusic_song" android:layout_marginLeft="15dp" android:textColor="#0d0c0c" android:layout_toRightOf="@+id/item_mymusic_singer" android:text="时间" android:textSize="15sp" /> </RelativeLayout> </LinearLayout>
记得加上权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />