实现本地音乐选择,播放,带可拖动进度条

来源:互联网 发布:和平网络电视手机版 编辑:程序博客网 时间:2024/05/06 00:14

需求:项目需要实现扫描本地sdcard上的所有音乐.并且可以进行播放,带可拖动进度条。

实现步骤:1.每个音乐文件在数据中有一条记录,开启一个线程查找数据库找出所有音乐文件,根据后缀名进行过滤,用handle通知ListView展示

                  2.ListView每一行设置单击事件,选中的那首歌曲进行播放。

                  3.ListView每一行都有seekBar,根据item选中进行显示隐藏。

1. activity文件 SelectMusicActivity.java

public class SelectMusicActivity extends Activity{private final static int MUSIC_SCARCH_FINISH = 1;//音乐扫描完成private ProgressDialog mProgressDialog;private List<MusicFile> musicFiles=new ArrayList<MusicFile>();private ListView listMusic;private MyAdapter myAdapter;private boolean isPlaying;//是否正在播放private int currentPosition = -1;private ViewHolder currentHolder;private MediaPlayer mediaPlayer=new MediaPlayer();//音乐播放工具private Handler mHandler=new Handler(){public void handleMessage(Message msg) {switch (msg.what) {case MUSIC_SCARCH_FINISH://音乐扫描完成mProgressDialog.dismiss();listMusic.setAdapter(myAdapter=new MyAdapter());break;}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_select_music);getMusicFloder();//查询本地所有音乐listMusic=(ListView) findViewById(R.id.list_music);}@Overrideprotected void onDestroy() {super.onDestroy();if(null!=mediaPlayer){mediaPlayer.release();mediaPlayer=null;isPlaying=false;}}//-------------------------私有类   私有方法---------------------private class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {// TODO Auto-generated method stubreturn musicFiles.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn musicFiles.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@SuppressLint("ResourceAsColor")@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {final ViewHolder holder;if(null==convertView){holder=new ViewHolder();convertView = LayoutInflater.from(SelectMusicActivity.this).inflate(R.layout.item_music_file,parent,false);holder.musicInfo=(LinearLayout) convertView.findViewById(R.id.music_info);holder.ivPlayState=(ImageView) convertView.findViewById(R.id.iv_play_state);holder.musicFolderName=(TextView) convertView.findViewById(R.id.music_folder_name);holder.musicDuration=(TextView) convertView.findViewById(R.id.music_duration);holder.rlMusicCapture=(RelativeLayout) convertView.findViewById(R.id.rl_music_capture);holder.sbProgress=(SeekBar) convertView.findViewById(R.id.sb_progress);holder.txtStartTime=(TextView) convertView.findViewById(R.id.txt_start_time);holder.txtEndTime=(TextView) convertView.findViewById(R.id.txt_end_time);convertView.setTag(holder);}else{holder=(ViewHolder) convertView.getTag();}MusicFile musicFile=musicFiles.get(position);holder.musicFolderName.setText(musicFile.getName().substring(1));holder.musicDuration.setText(Utils.getMusicDuration(musicFile.getMusicDuration()));holder.txtEndTime.setText(Utils.getMusicDuration(musicFile.getMusicDuration()));holder.sbProgress.setMax(musicFile.getMusicDuration());if (position == currentPosition) {holder.rlMusicCapture.setVisibility(View.VISIBLE);holder.musicInfo.setBackgroundColor(R.color.mainColor);}else{holder.rlMusicCapture.setVisibility(View.GONE);holder.musicInfo.setBackgroundColor(android.R.color.white);}holder.musicInfo.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {itemClick(holder,position);}});holder.sbProgress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar){}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {if(fromUser){if(mediaPlayer != null && isPlaying){mediaPlayer.seekTo(progress);holder.txtStartTime.setText(Utils.getMusicDuration(progress));}}}});return convertView;}}/** * 相当于List的点击事件 * @param holder * @param position */@SuppressLint("ResourceAsColor")private  void itemClick(ViewHolder holder,int position){MusicFile musicFile=musicFiles.get(position);if(position==currentPosition){//选中当前歌曲if(isPlaying){//播放中holder.ivPlayState.setImageResource(R.drawable.button_music_normal);mediaPlayer.pause();isPlaying=false;//position=-1的时候会隐藏下面的seekbar  并且背景颜色设置成白色position = -1;myAdapter.notifyDataSetChanged();}else{//暂停中holder.ivPlayState.setImageResource(R.drawable.button_music_selected);mediaPlayer.start();isPlaying=true;}}else{//选中其他歌曲if(currentPosition==-1){//第一次选中歌曲holder.ivPlayState.setImageResource(R.drawable.button_music_selected);musicPlay(musicFile.getDir());}else{musicPlay(musicFile.getDir());currentHolder.ivPlayState.setImageResource(R.drawable.button_music_normal);holder.ivPlayState.setImageResource(R.drawable.button_music_selected);}}currentPosition = position;myAdapter.notifyDataSetChanged();currentHolder=holder;}private  class ViewHolder{private LinearLayout musicInfo;private ImageView ivPlayState;private TextView musicFolderName;private TextView musicDuration;private RelativeLayout rlMusicCapture;//播放截取private SeekBar sbProgress;//截取进度条private TextView txtStartTime;//截取开始时间private TextView txtEndTime;//截取结束时间}/** * 播放歌曲 */private void musicPlay(String musicFile){try {mediaPlayer.reset();mediaPlayer.setDataSource(musicFile);mediaPlayer.prepare();mediaPlayer.start();isPlaying = true;} catch (Exception e) {e.printStackTrace();}}/** * 利用ContentProvider扫描手机中的音乐,此方法在运行在子线程中完成音乐的扫描,获取所有音乐文件 */private void getMusicFloder() {if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {Toast.makeText(this, "没有sdcard", 0).show();return;}// 显示进度条mProgressDialog = ProgressDialog.show(this,null,"正在加载中");new Thread(new Runnable() {@Overridepublic void run() {//查询音乐Uri mImageUri = Media.EXTERNAL_CONTENT_URI;ContentResolver mContentResolver = SelectMusicActivity.this.getContentResolver();String selection=Media.MIME_TYPE + "=? ";String[] selectionArgs=new String[]{"audio/mpeg"};Cursor mCursor = mContentResolver.query(mImageUri,null,selection,selectionArgs,Media.DATE_MODIFIED);while (mCursor.moveToNext()) {String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Audio.Media.DATA));int duration= mCursor.getInt(mCursor.getColumnIndex(MediaStore.Audio.Media.DURATION));MusicFile musicFile=new MusicFile();musicFile.setDir(path);musicFile.setMusicDuration(duration);musicFiles.add(musicFile);}mCursor.close();// 通知Handler扫描图片完成mHandler.sendEmptyMessage(MUSIC_SCARCH_FINISH);}}).start();}}

2.音乐文件对应实体类  MusicFile.java

/** * 音乐文件对应实体类 */public class MusicFile{private String dir;//音乐绝对路径private String name;//音乐名称private int musicDuration;//音乐时长public String getDir() {return dir;}public void setDir(String dir) {this.dir = dir;int lastIndexOf = this.dir.lastIndexOf("/");this.name = this.dir.substring(lastIndexOf);}public String getName() {return name;}public int getMusicDuration() {return musicDuration;}public void setMusicDuration(int musicDuration) {this.musicDuration = musicDuration;}}


3.工具类,封装一些静态方法   Utils.java

public class Utils {/** * 判断文件是否是图片 * @param fileName * @return */public static boolean isImage(String fileName){if (fileName.endsWith(".jpg")|| fileName.endsWith(".JPG")|| fileName.endsWith(".png")|| fileName.endsWith(".PNG")|| fileName.endsWith(".jpeg")|| fileName.endsWith(".JPEG")|| fileName.endsWith(".gif")|| fileName.endsWith(".GIF"))return true;return false;}/** * 根据资源ID得到字符串 * @param context * @param resId * @return */public static String getStringByResId(Context context,int resId){return context.getString(resId);}public static String getMusicDuration(int duration){SimpleDateFormat sdf=new SimpleDateFormat("mm:ss");return sdf.format(duration);}}



4.activity_select_music.xml    里面就一个ListView

<?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="match_parent"    android:orientation="vertical" >    <ListView        android:id="@+id/list_music"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/></LinearLayout>

5.ListView的Item布局文件   item_music_file.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content">    <LinearLayout        android:paddingTop="15dp"    android:paddingBottom="15dp"        android:id="@+id/music_info"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:orientation="horizontal" >        <ImageView            android:id="@+id/iv_play_state"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:src="@drawable/button_music_normal" />        <TextView            android:id="@+id/music_folder_name"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="4"            android:gravity="left"            android:maxLines="1"            android:text="本地声音文件名称"            android:textSize="16sp" />        <TextView            android:id="@+id/music_duration"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_marginRight="9dp"            android:layout_weight="1"            android:gravity="right"            android:text="0:00"            android:textColor="#848484"            android:textSize="14sp" />    </LinearLayout>        <RelativeLayout        android:id="@+id/rl_music_capture"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/music_info"        android:background="#1D1D1D"        android:padding="9dp">        <SeekBar            android:id="@+id/sb_progress"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_below="@+id/txt_start_time"            android:layout_gravity="center_vertical"            android:layout_marginLeft="4dp"            android:layout_marginRight="4dp"            android:maxHeight="36dip"            android:minHeight="36dip"            android:paddingLeft="20dp"            android:paddingRight="12dp"            android:background="#1D1D1D"            android:progressDrawable="@drawable/bg_bar"            android:thumb="@drawable/icon_seekbar_pointer"            android:thumbOffset="18dp" />        <TextView            android:id="@+id/txt_start_time"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentLeft="true"            android:layout_alignParentTop="true"            android:layout_marginLeft="9dp"            android:text="0:00"            android:textColor="#AFAFAF"            android:textSize="16sp" />        <TextView            android:id="@+id/txt_end_time"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_alignParentTop="true"            android:layout_marginRight="4dp"            android:text="4:50"            android:textColor="#AFAFAF"            android:textSize="16sp" />    </RelativeLayout></RelativeLayout>


效果图如下:



以上就是所有的源码跟效果图,有需要的朋友可以参考一下。推荐下自己创建的android QQ群:202928390   欢迎大家的加入


点击下载源码


推荐一个Android开发者必关注公众号,每周都有原创干货



0 0
原创粉丝点击