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

需求:项目需要实现扫描本地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;
	}
}


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   欢迎大家的加入


点击下载源码

原文地址:https://www.cnblogs.com/yishaochu/p/5078624.html