实现本地音乐选择,播放,带可拖动进度条-阿里云开发者社区

开发者社区> 数据库> 正文

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

简介:

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

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

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

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

1. activity文件 SelectMusicActivity.java

  1. public class SelectMusicActivity extends Activity{  
  2.     private final static int MUSIC_SCARCH_FINISH = 1;//音乐扫描完成  
  3.       
  4.     private ProgressDialog mProgressDialog;  
  5.     private List<MusicFile> musicFiles=new ArrayList<MusicFile>();  
  6.     private ListView listMusic;  
  7.     private MyAdapter myAdapter;  
  8.       
  9.     private boolean isPlaying;//是否正在播放  
  10.     private int currentPosition = -1;  
  11.     private ViewHolder currentHolder;  
  12.       
  13.     private MediaPlayer mediaPlayer=new MediaPlayer();//音乐播放工具  
  14.       
  15.     private Handler mHandler=new Handler(){  
  16.         public void handleMessage(Message msg) {  
  17.             switch (msg.what) {  
  18.             case MUSIC_SCARCH_FINISH://音乐扫描完成  
  19.                 mProgressDialog.dismiss();  
  20.                 listMusic.setAdapter(myAdapter=new MyAdapter());  
  21.                 break;  
  22.             }  
  23.         };  
  24.     };  
  25.       
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_select_music);  
  30.         getMusicFloder();//查询本地所有音乐  
  31.           
  32.         listMusic=(ListView) findViewById(R.id.list_music);  
  33.     }  
  34.       
  35.     @Override  
  36.     protected void onDestroy() {  
  37.         super.onDestroy();  
  38.         if(null!=mediaPlayer){  
  39.             mediaPlayer.release();  
  40.             mediaPlayer=null;  
  41.             isPlaying=false;  
  42.         }  
  43.     }  
  44.       
  45.     //-------------------------私有类   私有方法---------------------  
  46.     private class MyAdapter extends BaseAdapter{  
  47.         @Override  
  48.         public int getCount() {  
  49.             // TODO Auto-generated method stub  
  50.             return musicFiles.size();  
  51.         }  
  52.   
  53.         @Override  
  54.         public Object getItem(int position) {  
  55.             // TODO Auto-generated method stub  
  56.             return musicFiles.get(position);  
  57.         }  
  58.   
  59.         @Override  
  60.         public long getItemId(int position) {  
  61.             // TODO Auto-generated method stub  
  62.             return position;  
  63.         }  
  64.   
  65.         @SuppressLint("ResourceAsColor")  
  66.         @Override  
  67.         public View getView(final int position, View convertView, ViewGroup parent) {  
  68.             final ViewHolder holder;  
  69.             if(null==convertView){  
  70.                 holder=new ViewHolder();  
  71.                 convertView = LayoutInflater.from(SelectMusicActivity.this).inflate(R.layout.item_music_file,parent,false);  
  72.                 holder.musicInfo=(LinearLayout) convertView.findViewById(R.id.music_info);  
  73.                 holder.ivPlayState=(ImageView) convertView.findViewById(R.id.iv_play_state);  
  74.                 holder.musicFolderName=(TextView) convertView.findViewById(R.id.music_folder_name);  
  75.                 holder.musicDuration=(TextView) convertView.findViewById(R.id.music_duration);  
  76.                   
  77.                 holder.rlMusicCapture=(RelativeLayout) convertView.findViewById(R.id.rl_music_capture);  
  78.                 holder.sbProgress=(SeekBar) convertView.findViewById(R.id.sb_progress);  
  79.                 holder.txtStartTime=(TextView) convertView.findViewById(R.id.txt_start_time);  
  80.                 holder.txtEndTime=(TextView) convertView.findViewById(R.id.txt_end_time);  
  81.                 convertView.setTag(holder);  
  82.             }else{  
  83.                 holder=(ViewHolder) convertView.getTag();  
  84.             }  
  85.               
  86.             MusicFile musicFile=musicFiles.get(position);  
  87.             holder.musicFolderName.setText(musicFile.getName().substring(1));  
  88.             holder.musicDuration.setText(Utils.getMusicDuration(musicFile.getMusicDuration()));  
  89.             holder.txtEndTime.setText(Utils.getMusicDuration(musicFile.getMusicDuration()));  
  90.             holder.sbProgress.setMax(musicFile.getMusicDuration());  
  91.               
  92.             if (position == currentPosition) {  
  93.                 holder.rlMusicCapture.setVisibility(View.VISIBLE);  
  94.                   
  95.                 holder.musicInfo.setBackgroundColor(R.color.mainColor);  
  96.             }else{  
  97.                 holder.rlMusicCapture.setVisibility(View.GONE);  
  98.                 holder.musicInfo.setBackgroundColor(android.R.color.white);  
  99.             }  
  100.               
  101.             holder.musicInfo.setOnClickListener(new OnClickListener(){  
  102.                 @Override  
  103.                 public void onClick(View v) {  
  104.                     itemClick(holder,position);  
  105.                 }  
  106.             });  
  107.               
  108.             holder.sbProgress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {  
  109.                 @Override  
  110.                 public void onStopTrackingTouch(SeekBar seekBar) {}  
  111.                 @Override  
  112.                 public void onStartTrackingTouch(SeekBar seekBar){}  
  113.                 @Override  
  114.                 public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {  
  115.                     if(fromUser){  
  116.                         if(mediaPlayer != null && isPlaying){  
  117.                             mediaPlayer.seekTo(progress);  
  118.                             holder.txtStartTime.setText(Utils.getMusicDuration(progress));  
  119.                         }  
  120.                     }  
  121.                 }  
  122.             });  
  123.             return convertView;  
  124.         }  
  125.     }  
  126.       
  127.     /** 
  128.      * 相当于List的点击事件 
  129.      * @param holder 
  130.      * @param position 
  131.      */  
  132.     @SuppressLint("ResourceAsColor")  
  133.     private  void itemClick(ViewHolder holder,int position){  
  134.         MusicFile musicFile=musicFiles.get(position);  
  135.         if(position==currentPosition){//选中当前歌曲  
  136.             if(isPlaying){//播放中  
  137.                 holder.ivPlayState.setImageResource(R.drawable.button_music_normal);  
  138.                 mediaPlayer.pause();  
  139.                 isPlaying=false;  
  140.                   
  141.                 //position=-1的时候会隐藏下面的seekbar  并且背景颜色设置成白色  
  142.                 position = -1;  
  143.                 myAdapter.notifyDataSetChanged();  
  144.             }else{//暂停中  
  145.                 holder.ivPlayState.setImageResource(R.drawable.button_music_selected);  
  146.                 mediaPlayer.start();  
  147.                 isPlaying=true;  
  148.             }  
  149.         }else{//选中其他歌曲  
  150.             if(currentPosition==-1){//第一次选中歌曲  
  151.                 holder.ivPlayState.setImageResource(R.drawable.button_music_selected);  
  152.                 musicPlay(musicFile.getDir());  
  153.             }else{  
  154.                 musicPlay(musicFile.getDir());  
  155.                   
  156.                 currentHolder.ivPlayState.setImageResource(R.drawable.button_music_normal);  
  157.                 holder.ivPlayState.setImageResource(R.drawable.button_music_selected);  
  158.             }  
  159.         }  
  160.         currentPosition = position;  
  161.         myAdapter.notifyDataSetChanged();  
  162.         currentHolder=holder;  
  163.     }  
  164.       
  165.     private  class ViewHolder{  
  166.         private LinearLayout musicInfo;  
  167.         private ImageView ivPlayState;  
  168.         private TextView musicFolderName;  
  169.         private TextView musicDuration;  
  170.           
  171.         private RelativeLayout rlMusicCapture;//播放截取  
  172.         private SeekBar sbProgress;//截取进度条  
  173.         private TextView txtStartTime;//截取开始时间  
  174.         private TextView txtEndTime;//截取结束时间  
  175.     }  
  176.       
  177.     /** 
  178.      * 播放歌曲 
  179.      */  
  180.     private void musicPlay(String musicFile){  
  181.         try {  
  182.             mediaPlayer.reset();  
  183.             mediaPlayer.setDataSource(musicFile);  
  184.             mediaPlayer.prepare();  
  185.             mediaPlayer.start();  
  186.             isPlaying = true;  
  187.         } catch (Exception e) {  
  188.             e.printStackTrace();  
  189.         }  
  190.     }  
  191.       
  192.       
  193.     /** 
  194.      * 利用ContentProvider扫描手机中的音乐,此方法在运行在子线程中完成音乐的扫描,获取所有音乐文件 
  195.      */  
  196.     private void getMusicFloder() {  
  197.         if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {  
  198.             Toast.makeText(this"没有sdcard"0).show();  
  199.             return;  
  200.         }  
  201.         // 显示进度条  
  202.         mProgressDialog = ProgressDialog.show(this,null,"正在加载中");  
  203.         new Thread(new Runnable() {  
  204.             @Override  
  205.             public void run() {  
  206.                 //查询音乐  
  207.                 Uri mImageUri = Media.EXTERNAL_CONTENT_URI;  
  208.                 ContentResolver mContentResolver = SelectMusicActivity.this.getContentResolver();  
  209.                 String selection=Media.MIME_TYPE + "=? ";  
  210.                 String[] selectionArgs=new String[]{"audio/mpeg"};  
  211.                 Cursor mCursor = mContentResolver.query(mImageUri,null,selection,selectionArgs,Media.DATE_MODIFIED);  
  212.                 while (mCursor.moveToNext()) {  
  213.                     String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Audio.Media.DATA));  
  214.                     int duration= mCursor.getInt(mCursor.getColumnIndex(MediaStore.Audio.Media.DURATION));  
  215.                     MusicFile musicFile=new MusicFile();  
  216.                     musicFile.setDir(path);  
  217.                     musicFile.setMusicDuration(duration);  
  218.                     musicFiles.add(musicFile);  
  219.                 }  
  220.                 mCursor.close();  
  221.                 // 通知Handler扫描图片完成  
  222.                 mHandler.sendEmptyMessage(MUSIC_SCARCH_FINISH);  
  223.             }  
  224.         }).start();  
  225.     }  
  226. }  

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

  1. /** 
  2.  * 音乐文件对应实体类 
  3.  */  
  4. public class MusicFile{  
  5.     private String dir;//音乐绝对路径  
  6.     private String name;//音乐名称  
  7.     private int musicDuration;//音乐时长  
  8.       
  9.     public String getDir() {  
  10.         return dir;  
  11.     }  
  12.   
  13.     public void setDir(String dir) {  
  14.         this.dir = dir;  
  15.         int lastIndexOf = this.dir.lastIndexOf("/");  
  16.         this.name = this.dir.substring(lastIndexOf);  
  17.     }  
  18.       
  19.     public String getName() {  
  20.         return name;  
  21.     }  
  22.   
  23.     public int getMusicDuration() {  
  24.         return musicDuration;  
  25.     }  
  26.   
  27.     public void setMusicDuration(int musicDuration) {  
  28.         this.musicDuration = musicDuration;  
  29.     }  
  30. }  


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

  1. public class Utils {  
  2.     /** 
  3.      * 判断文件是否是图片 
  4.      * @param fileName 
  5.      * @return 
  6.      */  
  7.     public static boolean isImage(String fileName){  
  8.         if (fileName.endsWith(".jpg")|| fileName.endsWith(".JPG")|| fileName.endsWith(".png")|| fileName.endsWith(".PNG")  
  9.                 || fileName.endsWith(".jpeg")|| fileName.endsWith(".JPEG")|| fileName.endsWith(".gif")|| fileName.endsWith(".GIF"))  
  10.             return true;  
  11.         return false;  
  12.     }  
  13.       
  14.     /** 
  15.      * 根据资源ID得到字符串 
  16.      * @param context 
  17.      * @param resId 
  18.      * @return 
  19.      */  
  20.     public static String getStringByResId(Context context,int resId){  
  21.         return context.getString(resId);  
  22.     }  
  23.       
  24.     public static String getMusicDuration(int duration){  
  25.         SimpleDateFormat sdf=new SimpleDateFormat("mm:ss");  
  26.         return sdf.format(duration);  
  27.     }  
  28. }  



4.activity_select_music.xml    里面就一个ListView

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <ListView  
  8.         android:id="@+id/list_music"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"/>  
  11.   
  12. </LinearLayout>  

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

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="wrap_content">  
  5.   
  6.     <LinearLayout  
  7.         android:paddingTop="15dp"  
  8.             android:paddingBottom="15dp"  
  9.         android:id="@+id/music_info"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:gravity="center"  
  13.         android:orientation="horizontal" >  
  14.   
  15.         <ImageView  
  16.             android:id="@+id/iv_play_state"  
  17.             android:layout_width="0dp"  
  18.             android:layout_height="wrap_content"  
  19.             android:layout_weight="1"  
  20.             android:src="@drawable/button_music_normal" />  
  21.   
  22.         <TextView  
  23.             android:id="@+id/music_folder_name"  
  24.             android:layout_width="0dp"  
  25.             android:layout_height="wrap_content"  
  26.             android:layout_weight="4"  
  27.             android:gravity="left"  
  28.             android:maxLines="1"  
  29.             android:text="本地声音文件名称"  
  30.             android:textSize="16sp" />  
  31.   
  32.         <TextView  
  33.             android:id="@+id/music_duration"  
  34.             android:layout_width="0dp"  
  35.             android:layout_height="wrap_content"  
  36.             android:layout_marginRight="9dp"  
  37.             android:layout_weight="1"  
  38.             android:gravity="right"  
  39.             android:text="0:00"  
  40.             android:textColor="#848484"  
  41.             android:textSize="14sp" />  
  42.     </LinearLayout>  
  43.       
  44.     <RelativeLayout  
  45.         android:id="@+id/rl_music_capture"  
  46.         android:layout_width="match_parent"  
  47.         android:layout_height="wrap_content"  
  48.         android:layout_below="@+id/music_info"  
  49.         android:background="#1D1D1D"  
  50.         android:padding="9dp">  
  51.   
  52.         <SeekBar  
  53.             android:id="@+id/sb_progress"  
  54.             android:layout_width="match_parent"  
  55.             android:layout_height="wrap_content"  
  56.             android:layout_below="@+id/txt_start_time"  
  57.             android:layout_gravity="center_vertical"  
  58.             android:layout_marginLeft="4dp"  
  59.             android:layout_marginRight="4dp"  
  60.             android:maxHeight="36dip"  
  61.             android:minHeight="36dip"  
  62.             android:paddingLeft="20dp"  
  63.             android:paddingRight="12dp"  
  64.             android:background="#1D1D1D"  
  65.             android:progressDrawable="@drawable/bg_bar"  
  66.             android:thumb="@drawable/icon_seekbar_pointer"  
  67.             android:thumbOffset="18dp" />  
  68.   
  69.         <TextView  
  70.             android:id="@+id/txt_start_time"  
  71.             android:layout_width="wrap_content"  
  72.             android:layout_height="wrap_content"  
  73.             android:layout_alignParentLeft="true"  
  74.             android:layout_alignParentTop="true"  
  75.             android:layout_marginLeft="9dp"  
  76.             android:text="0:00"  
  77.             android:textColor="#AFAFAF"  
  78.             android:textSize="16sp" />  
  79.   
  80.         <TextView  
  81.             android:id="@+id/txt_end_time"  
  82.             android:layout_width="wrap_content"  
  83.             android:layout_height="wrap_content"  
  84.             android:layout_alignParentRight="true"  
  85.             android:layout_alignParentTop="true"  
  86.             android:layout_marginRight="4dp"  
  87.             android:text="4:50"  
  88.             android:textColor="#AFAFAF"  
  89.             android:textSize="16sp" />  
  90.     </RelativeLayout>  
  91. </RelativeLayout>  


效果图如下:



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


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
数据库
使用钉钉扫一扫加入圈子
+ 订阅

分享数据库前沿,解构实战干货,推动数据库技术变革

其他文章