android实现音乐播放器(进度条)

|--效果图

|--依赖3个对象

    MediaPlayer:实现音乐播放,暂停,缓冲。
    SeekBar:滑动的进度条。

    java.util.Timer:定时器,时时更新进度条。

|--main.xml样式文件

<span style="font-size:14px;">    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <EditText
        android:id="@+id/mediaFileName"
        android:layout_width="match_parent"
        android:text="gangstabop.mp3"
        android:layout_height="wrap_content" >
        <requestFocus />
    </EditText>


    <LinearLayout
        android:id="@+id/linearButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/playButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/stop" />

        <SeekBar
            android:id="@+id/playSeekBar"
            android:layout_width="140px"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3px"
            android:layout_marginTop="5px" />

        <Button
            android:id="@+id/replayButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3px"
            android:text="@string/replay" />
    </LinearLayout></span><span style="font-size: 24px;">
</span>

|--Activity实现代码

<span style="font-size:14px;">/**
 * @CreateDate 2015-2-3
 * @Author hubiao
 * @Title 音乐播放器
 */
public class MediaActivity extends Activity {
	private MediaPlayer mediaPlayer;//媒体播放器
	private Button playButton;
	private Button replayButton ;
	private boolean isCellPlay;/*在挂断电话的时候,用于判断是否为是来电时中断*/
	private boolean isSeekBarChanging;//互斥变量,防止进度条与定时器冲突。
	private int currentPosition;//当前音乐播放的进度
	private SeekBar seekBar;
	private Timer timer;
	
	private static final String TAG = "MediaActivity";
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		//实例化媒体播放器
		mediaPlayer = new MediaPlayer();
		
		//监听滚动条事件
		seekBar = (SeekBar) findViewById(R.id.playSeekBar);
		seekBar.setOnSeekBarChangeListener(new MySeekBar());
		
		// 监听[播放或暂停]事件
		playButton= (Button) findViewById(R.id.playButton);
		playButton.setOnClickListener(new PalyListener());
		
		//监听[重播]事件
		replayButton= (Button) findViewById(R.id.replayButton);
		replayButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				mediaPlayer.reset();
				currentPosition = 0;
				play();
			}
		});
		
		//监听来电事件
		TelephonyManager phoneyMana = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
		phoneyMana.listen(new myPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);
	}
	/*销毁时释资源*/
	@Override
	protected void onDestroy() {
		mediaPlayer.release();
		timer.cancel();
		timer = null;
		mediaPlayer = null;
		super.onDestroy();
	}
	
	/*播放或暂停事件处理*/
	private class PalyListener implements OnClickListener {
		public void onClick(View v) {
			if(playButton.getText().toString().equals("播放"))
			{
				currentPosition = mediaPlayer.getCurrentPosition();//记录播放的位置
				mediaPlayer.stop();//暂停状态
				playButton.setText(R.string.stop);
				timer.purge();//移除所有任务;
			}
			else{
				mediaPlayer.reset();
				play();
			}
		}
	}
	
	/*播放处理*/
	private void play() {
		File media = new File("/mnt/sdcard/files/","bewithyou.mp3");//由于是练习,就把mp3名称固定了
		Log.i(TAG, media.getAbsolutePath());
		if(media.exists())
		{
			try {
				mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//设置音频类型
				mediaPlayer.setDataSource(media.getAbsolutePath());//设置mp3数据源
				mediaPlayer.prepareAsync();//数据缓冲
				/*监听缓存 事件,在缓冲完毕后,开始播放*/
				mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
					public void onPrepared(MediaPlayer mp) {
						mp.start();	
						mp.seekTo(currentPosition);
						playButton.setText(R.string.play);
						seekBar.setMax(mediaPlayer.getDuration());
					}
				});
				//监听播放时回调函数
				timer = new Timer();
				timer.schedule(new TimerTask() {
					@Override
					public void run() {
						if(!isSeekBarChanging){
							seekBar.setProgress(mediaPlayer.getCurrentPosition());
						}
					}
				},0,50);
			} catch (Exception e) {
				Toast.makeText(getApplicationContext(), R.string.playError, Toast.LENGTH_LONG).show();
				e.printStackTrace();
				System.out.println(e);
			}
		}
		else{
			Toast.makeText(getApplicationContext(), R.string.fileError, Toast.LENGTH_LONG).show();
		}
	}
	
	/*来电事件处理*/
	private class myPhoneStateListener extends PhoneStateListener
	{
		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
		switch (state) {
			case TelephonyManager.CALL_STATE_RINGING://来电,应当停止音乐
				if(mediaPlayer.isPlaying() && playButton.getText().toString().equals("播放")){
					currentPosition = mediaPlayer.getCurrentPosition();//记录播放的位置
					mediaPlayer.stop();
					isCellPlay = true;//标记这是属于来电时暂停的标记
					playButton.setText(R.string.stop);
					timer.purge();//移除定时器任务;
				}
				break;
			case TelephonyManager.CALL_STATE_IDLE://无电话状态
				if(isCellPlay){
					isCellPlay = false;
					mediaPlayer.reset();
					play();
				}
				break;
			}
		}
	}
	
	/*进度条处理*/
	public class MySeekBar implements OnSeekBarChangeListener{

		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
		}

		/*滚动时,应当暂停后台定时器*/
		public void onStartTrackingTouch(SeekBar seekBar) {
			isSeekBarChanging = true;
		}
		/*滑动结束后,重新设置值*/
		public void onStopTrackingTouch(SeekBar seekBar) {
			isSeekBarChanging = false;
			mediaPlayer.seekTo(seekBar.getProgress());
		}
	}
}</span>

|--补充
   1:如果mp3在sd中,如播放失败,是否申请sd访问权限或mp3文件是否存在。
   2:MediaPlayer对有个别的音频好像不太支持,如果路径正确,权限具备还无法播放,就考虑下音频问题。
   3:本案例用到的权限。
    <!-- 申请SD卡写入权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!--申请SD卡创建与权限  -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <!-- 拦截号码权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>


   


   

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页