实现本地音乐选择,播放,带可拖动进度条
来源:互联网 发布:和平网络电视手机版 编辑:程序博客网 时间: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;}}
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
- 实现本地音乐选择,播放,带可拖动进度条
- 带进度条的播放音乐
- android音乐播放器,可进度条调节
- Android——音乐播放器完善——进度条显示当前播放进度,加可拖动进度条 绑定方式通信
- Android用MediaPlay方法实现本地音乐的播放,与进度条的实现
- Android带播放进度条的音乐播放器
- Jquery实现鼠标可拖动的进度条
- android实现音乐播放器(进度条)
- 实现音乐播放器,多线程处理进度条
- android实现音乐播放器(进度条)
- 可拖动的进度条
- 自定义音乐播放进度条
- android 播放音乐-进度条
- 能实现播放本地音乐的Demo
- 简单实现Android本地音乐的播放
- android 实现音乐播放器 带 seekbar
- 音乐播放器--简单实现播放、暂停、随机播放、音乐进度条(第一版)
- 视频支持拖动进度条播放的实现(基于nginx)
- [MFC]匈牙利标记法、MFC基本结构
- [leetcode][two pointers] Remove Duplicates from Sorted Array II
- PAT 1020. Tree Traversals (25)
- fastJson
- UIHelper的两个自动递归获取节点的函数(返回Node *)
- 实现本地音乐选择,播放,带可拖动进度条
- leetcode Add Binary
- 变废为宝-行之有道
- nginx服务器部署pathinfo
- P198 1
- 最省钱的考研复习
- ruby 1.8.7版本升级1.9.3
- P198 2
- P198 3