一个简单的音乐播放器

主要功能,遍历的SD卡,播放、暂停、上一首、下一首、拖动进度条播放、播放完一首就自动播放下一首,显示当前进度条时间的刷新,每首歌曲总时间的刷新,PopupWindow弹出一个ListView,歌曲名字的后缀名分割,

这儿注意就是:mPopupWindom.setFocusable(true);// 此方法可以保证PopupWindom里面嵌套的ListView有点击响应。

声明各种控件.

 

	private ImageView mUpMusicBtn, mStartAndSuspendMusicBtn, mNextMusicBtn,
			mListMusicBtn;
	private SeekBar mSeekBar;
	private TextView mTitleMusicNameText, mCurrentTimeText, mAllTimeText;
	private Handler mHandler = new Handler();// 刷新当前播放时的时间
	private MediaPlayer mediaPlay = new MediaPlayer();


	String filePath;

	private PopupWindow mPopupWindom;
	private LayoutInflater mInflater;
	//SD卡的目录
	private File allFile = Environment.getExternalStorageDirectory();
	// 装遍历出来的音乐文件的名字
	private List<File> fileName = new ArrayList<File>();
	// 装遍历出来的音乐文件的名字,是分割过后的音乐文件名字,没有后缀名
	private ArrayList<String> sdcardMusicName = new ArrayList<String>();
	// 等于当前点的哪一项, 在上一首和下一首中用到;点击上一首和下一首时也会再次被实例化
	private int listMusicChecked;


加载布局和遍历文件、SeekBar拖动的监听等:

 

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_kugou_music);

		getFileWithMusic(allFile);// 遍历文件获取音乐文件

		example();// 实例化控件
		new Thread(new RefrshTime()).start();// 设置进度条的刷新

		mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			public void onStopTrackingTouch(SeekBar seekBar) {
				// 停止拖动进度条时,音乐开始播放

			}

			public void onStartTrackingTouch(SeekBar seekBar) {
				// 开始拖动进度条时,音乐暂停播放

			}

			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
				// fromUser判断是用户改变的滑块的值,拖动SeekBar的监听并响应
				if (fromUser == true) {
					mediaPlay.seekTo(progress);
				}
			}
		});
	}


封装实例化控件的方法:

 

	/**
	 * 实例化控件
	 */
	public void example() {
		mUpMusicBtn = (ImageView) findViewById(R.id.copy_kuguo_up_music_btn);
		mStartAndSuspendMusicBtn = (ImageView) findViewById(R.id.copy_kuguo_start_and_suspend_music_btn);
		mNextMusicBtn = (ImageView) findViewById(R.id.copy_kuguo_next_music_btn);
		mListMusicBtn = (ImageView) findViewById(R.id.copy_kugou_list_music_imagebtn);

		mTitleMusicNameText = (TextView) findViewById(R.id.title_music_name_text);
		mCurrentTimeText = (TextView) findViewById(R.id.copy_kuguo_current_time_text);
		mAllTimeText = (TextView) findViewById(R.id.copy_kuguo_all_time_text);

		mSeekBar = (SeekBar) findViewById(R.id.copy_kuguo_seekbar);
		mInflater = LayoutInflater.from(this);

		mUpMusicBtn.setOnClickListener(this);
		mStartAndSuspendMusicBtn.setOnClickListener(this);
		mNextMusicBtn.setOnClickListener(this);
		mListMusicBtn.setOnClickListener(this);
	}


播放器的初始化准备阶段方法:

	/**
	 * 播放器里面歌曲的准备阶段
	 */
	public void musicMediaPlayerPrepare(String s) {
		try {
			mediaPlay.setDataSource(s);
			mediaPlay.prepare();
			mediaPlay.start();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

点击暂停、开始的方法:

	/**
	 * 要恶魔暂停,要么播放
	 */
	public void startMusic() {
		if (!mediaPlay.isPlaying()) {
			mStartAndSuspendMusicBtn
					.setImageResource(R.drawable.kg_lock_screen_pause_button_pressed);
			mediaPlay.start();//播放
		} else {
			mStartAndSuspendMusicBtn
					.setImageResource(R.drawable.kg_lock_screen_play_button_pressed);
			mediaPlay.pause();//暂停
		}
	}


各种控件监听的方法:

	/**
	 * 控件的监听
	 */
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.copy_kuguo_up_music_btn:// 上一首按钮
			if (listMusicChecked - 1 < 0) {// 数组从0开始计数
				Toast.makeText(this, "已经是第一个了", 0).show();

				listMusicChecked = 0;//再一次赋值,更新
			} else {
				mediaPlay.reset();// 重置
				musicMediaPlayerPrepare("File://"
						+ fileName.get(listMusicChecked - 1));// 传入歌曲,
				// 设置title上面显示的名字
				Log.i("11", "名字数组对象:" + sdcardMusicName);
				String divicionUpName = musicNameToTitle(sdcardMusicName
						.get(listMusicChecked - 1));
				mTitleMusicNameText.setText(divicionUpName);//Title处显示当前播放歌曲的名字

				listMusicChecked = listMusicChecked - 1;//再一次赋值,更新
			}
			break;
		case R.id.copy_kuguo_start_and_suspend_music_btn:// 暂停,开始按钮
			startMusic();
			break;
		case R.id.copy_kuguo_next_music_btn:// 下一首按钮
			if (listMusicChecked + 1 < fileName.size()) {// 数组从0开始计数

				mediaPlay.reset();// 重置
				musicMediaPlayerPrepare("File://"
						+ fileName.get(listMusicChecked + 1));// 传入歌曲,
				// 设置title上面显示的名字
				String divicionNextName = musicNameToTitle(sdcardMusicName
						.get(listMusicChecked + 1));
				mTitleMusicNameText.setText(divicionNextName);

				listMusicChecked = listMusicChecked + 1;//再一次赋值,更新
			} else {
				Toast.makeText(this, "已经是最后一个了", 0).show();
				listMusicChecked = fileName.size();
			}
			break;
		case R.id.copy_kugou_list_music_imagebtn:
			listMusicForPopupWindom();// 弹出音乐列表窗口
			break;
		}
	}


PopupWindow的效果:

	/**
	 * 点击Title最右边的按钮弹出音乐列表窗口,用PopupWindom来实现
	 */
	public void listMusicForPopupWindom() {
		//高度要适当的设置
		mPopupWindom = new PopupWindow(getListViewForPopupWindom(), 700, 500);
		mPopupWindom.setFocusable(true);// 此方法可以保证PopupWindom里面嵌套的ListView有点击响应
		// 下面这三行代码可以让你点击空白处来关闭PopWindow 弹出的窗口
		mPopupWindom.setTouchable(true);
		mPopupWindom.setOutsideTouchable(true);
		mPopupWindom.setBackgroundDrawable(new BitmapDrawable());

		// 点击按钮就弹出窗口
		mListMusicBtn.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				if (mPopupWindom.isShowing()) {// 判断窗口是否已经弹出弹出
					// mPopWind.setOutsideTouchable(false);
					mPopupWindom.dismiss();// 关闭窗口
				} else {
					mPopupWindom.showAsDropDown(v);// 弹出窗口
				}
			}
		});

	}


ListView的监听、以及返回PopupWindow所需要的View:

	/**
	 * 把装有ListView的布局返回给PopupWindom的实例化中,才有弹窗的布局类型
	 */
	public View getListViewForPopupWindom() {
		View v = mInflater.inflate(R.layout.copykugou_listview_music_layout,
				null);
		ListView mListview = (ListView) v
				.findViewById(R.id.copykugou_listview_to_musicname);
		TextView allMusicPopupText = (TextView) v
				.findViewById(R.id.popupwindow_allmusic_to_text);
		allMusicPopupText.setText("总共" + fileName.size() + "首歌曲");
		ListMusicAdapter listBaseadapter = new ListMusicAdapter(this);
		mListview.setAdapter(listBaseadapter);
		listBaseadapter.setData(fileName);

		// popupWindom弹出的ListView的监听
		mListview.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				listMusicChecked = position;// 实例化计数器,用于上一首,下一首
				ListMusicAdapter fileBackAdapter = (ListMusicAdapter) parent
						.getAdapter();
				//获得适配器的每一项
				File fileBack = (File) fileBackAdapter.getItem(position);
				String backPrepareMusic = fileBack.getPath();
				
				if (mediaPlay.isPlaying()) {
					mediaPlay.reset();
				}
				// 歌曲的地址传过去才能播放
				musicMediaPlayerPrepare("file://" + backPrepareMusic);
				// title上显示播放歌曲的名字
				mTitleMusicNameText.setText(musicNameToTitle(fileBack.getName()));
				// 点击PopupWindow后,点击ListView里面的任意一项时,就关闭窗口
				mPopupWindom.dismiss();
			}
		});

		return v;
	}

遍历mp3文件,递归的运用:

	/**
	 * 无限遍历一个文件夹,找出音乐文件,并添加到List里面,然后设置给适配器
	 */
	public void getFileWithMusic(File fileAddress) {
		if (fileAddress != null) {
			File[] fileList = fileAddress.listFiles();
			if (fileList != null) {
				for (File f : fileList) {
					if (f.isDirectory()) {
						getFileWithMusic(f);
					} else {
						String s = f.getName();
						if (s.endsWith(".mp3") || s.endsWith(".apk")) {
							fileName.add(f);
							Log.i("11", "歌曲的名字:" + s);
							sdcardMusicName.add(s);
						}
					}
				}
			}
		}

	}

歌曲后缀名的分割,android中需要加[ ] ,用点(.)分割:

 

	/**
	 * 分割歌曲的后缀名
	 */
	public String musicNameToTitle(String s) {
		// xinyang.mp3
		String[] divisionMusicName = s.split("[.]");
		return divisionMusicName[0];
	}


进度条的刷新以及、时间的刷新、检测播放完自动播放下一首:

 

	/**
	 * 刷新进度条,Handler在主线程中实例化,刷新当前播放的时间,用TextView来显示当前时间和,总的时间
	 */
	public class RefrshTime implements Runnable {
		public void run() {
			while (true) {
				if (mediaPlay.isPlaying() && mediaPlay != null) {
					mSeekBar.setMax(mediaPlay.getDuration());
					mSeekBar.setProgress(mediaPlay.getCurrentPosition());
				}
				mHandler.post(new Runnable() {
					public void run() {
						if (mediaPlay != null && !mediaPlay.isPlaying()) {
							mAllTimeText.setText("00:00");
							mCurrentTimeText.setText("00:00");
						} else {
							// 设置总的时间
							int allTimePoint = (mediaPlay.getDuration() / 1000) / 60;
							int allTimeSec = (mediaPlay.getDuration() / 1000) % 60;
							if (allTimePoint < 10 && allTimeSec < 10) {
								mAllTimeText.setText("0" + allTimePoint + ":"
										+ allTimeSec);
							} else if (allTimePoint < 10 && allTimeSec >= 10) {
								mAllTimeText.setText("0" + allTimePoint + ":"
										+ allTimeSec);
							} else if (allTimePoint > 10 && allTimeSec < 10) {
								mAllTimeText.setText(allTimePoint + ":0"
										+ allTimeSec);
							} else if (allTimePoint > 10 && allTimeSec >= 10) {
								mAllTimeText.setText(allTimePoint + ":0"
										+ allTimeSec);
							}

							// 设置当前的时间
							int currentPoint = (mediaPlay.getCurrentPosition() / 1000) / 60;
							int currentSec = (mediaPlay.getCurrentPosition() / 1000) % 60;
							if (currentPoint < 10 && currentSec < 10) {
								mCurrentTimeText.setText("0" + currentPoint
										+ ":0" + currentSec);
							} else if (currentPoint < 10 && currentSec >= 10) {
								mCurrentTimeText.setText("0" + currentPoint
										+ ":" + currentSec);
							} else if (currentPoint > 10 && currentSec < 10) {
								mCurrentTimeText.setText(currentPoint + ":0"
										+ currentSec);
							} else if (currentPoint > 10 && currentSec >= 10) {
								mCurrentTimeText.setText(currentPoint + ":"
										+ currentSec);
							}
							// 自动播放下一首
							if (allTimeSec == currentSec) {
								if (listMusicChecked + 1 < fileName.size()) {// 数组从0开始计数

									mediaPlay.reset();// 重置
									musicMediaPlayerPrepare("File://"
											+ fileName
													.get(listMusicChecked + 1));// 传入歌曲,
									// 设置title上面显示的名字
									String divicionNextName = musicNameToTitle(sdcardMusicName
											.get(listMusicChecked + 1));
									mTitleMusicNameText
											.setText(divicionNextName);

									listMusicChecked = listMusicChecked + 1;
								} else {
									listMusicChecked = fileName.size();
								}
								Toast.makeText(CopyKugouMainActivity.this,
										"播放下一首", 0).show();
							}
						}
					}
				});
				try {
					// 设置刷新的时间
					Thread.sleep(1000 - (mediaPlay.getCurrentPosition() % 1000));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}
		}

	}





 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值