需求:项目需要实现扫描本地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; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_select_music); getMusicFloder();//查询本地所有音乐 listMusic=(ListView) findViewById(R.id.list_music); } @Override protected void onDestroy() { super.onDestroy(); if(null!=mediaPlayer){ mediaPlayer.release(); mediaPlayer=null; isPlaying=false; } } //-------------------------私有类 私有方法--------------------- private class MyAdapter extends BaseAdapter{ @Override public int getCount() { // TODO Auto-generated method stub return musicFiles.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return musicFiles.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @SuppressLint("ResourceAsColor") @Override public 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(){ @Override public void onClick(View v) { itemClick(holder,position); } }); holder.sbProgress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) {} @Override public void onStartTrackingTouch(SeekBar seekBar){} @Override public 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() { @Override public 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; } }
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 欢迎大家的加入