需求:项目需要实现扫描本地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 欢迎大家的加入