android简单实现音乐播放器

      程序实现如下功能:当点击播放按钮,按钮进行播放音乐,同时按钮背景图片切换成暂停按钮,当点击暂停按钮时,音乐暂停播放,同时按钮背景图片切换成播放按钮,点击重置按钮,音乐停止播放。


效果图如下:


首先简述下编写思路:
      程序通过service与广播接收者实现。在主功能代码中发送广播,有一个命令广播接收者,用来接收命令,一个更新UI的广播接收者,用来接收命令广播发送过来的状态,根据状态更新UI。


给出代码:

首先是布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ProgressBar 
        android:id="@+id/pb"
        android:layout_marginTop="3dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@android:style/Widget.ProgressBar.Horizontal"
        />

    <TextView 
        android:id="@+id/tv"
        android:layout_marginTop="8dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="0:00/0:00"
        android:textSize="12sp"
        />
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:orientation="horizontal"
        >
        <ImageButton 
            android:id="@+id/pause"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/pause"
            />
        <ImageButton 
            android:id="@+id/stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/stop"
            android:layout_marginLeft="5dp"
            />
    </LinearLayout>
</LinearLayout>

布局文件给出一个进度条,一个TextView控件,用来标识播放进度,一个播放暂停按钮,一个重置按钮,成垂直布局。

接下来实现主功能代码:

package com.example.sample5_11tdw;

import android.support.v7.app.ActionBarActivity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;

public class MainActivity extends ActionBarActivity {

	private ImageButton pause;//暂停
	private ImageButton stop;//停止
	
	private String path = "/sdcard/zdan.mp3";
	
	private UpateUIReceiver uuRece;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		InitViews();
	}
	
	private void InitViews() {
		pause = (ImageButton) findViewById(R.id.pause);
		stop = (ImageButton) findViewById(R.id.stop);
		uuRece = new UpateUIReceiver(this);
		
		//当前状态为暂停,点击后进行播放
		pause.setOnClickListener(new View.OnClickListener() {//暂停事件监听
			
			@Override
			public void onClick(View v) {
				if(uuRece.status == Constanly.STATUS_PLAY){//如果当前状态为播放
					Intent intent = new Intent(Constanly.MUSIC_CONTROL);
					//发送暂停命令
					intent.putExtra("cmd", Constanly.COMMAND_PAUSE);
					MainActivity.this.sendBroadcast(intent);
				}else if(uuRece.status == Constanly.STATUS_STOP)
				{
					//当前状态为暂停
					Intent intent = new Intent(Constanly.MUSIC_CONTROL);
					intent.putExtra("path", path);
					intent.putExtra("cmd", Constanly.COMMAND_PLAY);
					MainActivity.this.sendBroadcast(intent);
				}else if(uuRece.status == Constanly.STATUS_PAUSE)
				{//若当前状态为暂停,则继续播放
					Intent intent = new Intent(Constanly.MUSIC_CONTROL);
					intent.putExtra("cmd", Constanly.COMMAND_PLAY);
					MainActivity.this.sendBroadcast(intent);
				}
			}
		});
		
		
		stop.setOnClickListener(new View.OnClickListener() {//停止事件监听,将播放的路径发送过去
			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(Constanly.MUSIC_CONTROL);
				intent.putExtra("cmd", Constanly.COMMADN_STOP);
				MainActivity.this.sendBroadcast(intent);
			}
		});
		
		//动态注册更新UI的广播事件
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(Constanly.UPDATE_UI);
		registerReceiver(uuRece, intentFilter);
		
		this.startService(new Intent(MainActivity.this,MyMusicService.class));
	}
	
	@SuppressWarnings("deprecation")
	@Override
	protected void onStart() {
		super.onStart();
		NotificationManager nm =  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		Intent intent = new Intent(this,MainActivity.class);
		//将Intent封装为PendingIntent
		PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
		Notification notification = new Notification();
		notification.icon = R.drawable.notilogo;
		notification.vibrate = new long[]{200,300};//200毫秒后震动300毫秒
		notification.setLatestEventInfo(this, "音乐播放器正在运行中", "单击查看", pi);
		nm.notify(0,notification);
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		this.unregisterReceiver(uuRece);
	}
}

在主功能代码中获取按钮控件,为按钮控件设置事件监听,当点击播放暂停按钮时,需要判断当前的状态,如果为停止状态,则需要将路径,播放命令发送出去,如果为暂停状态,发送播放状态即可,在命令广播接收类中通过判断命令来对应相应的操作。同时动态注册命令接收广播,启动服务。

给出命令广播接收类:

package com.example.sample5_11tdw;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Looper;
import android.view.LayoutInflater;
import android.widget.ImageButton;

public class CommandReceiver extends BroadcastReceiver{

	public MediaPlayer mp;
	public int status;
	
	@Override
	public void onReceive(final Context context, Intent intent) {
		switch (intent.getIntExtra("cmd", -1)) {
		case Constanly.COMMAND_PLAY:
			String path = intent.getStringExtra("path");
			if(path != null){//path不为空,说明是停止后重新播放
				//说明之前已经有MediaPlayer对象了,要进行释放
				if(mp != null){
					mp.release();
				}
				 mp=new MediaPlayer();
				try {
					//为音乐播放器添加完成监听
					mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
						//歌曲播放完毕
						@Override
						public void onCompletion(MediaPlayer mp) {
							mp.stop();
							status = Constanly.STATUS_STOP;
							updateUI(context);
						}
					});
					
					mp.setDataSource(path);
					//通过new MediaPlayer()一定要先进行prepare()
					mp.prepare();
					//开始播放
					mp.start();
				}  catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				//发送消息改变进度条的进度
				new Thread(){
					@Override
					public void run() {
						Looper:while(true){
							//如果当前状态为停止状态
							if(status == Constanly.STATUS_STOP){
								break Looper;
							}
							int duration = 0;//总时间
							int current = 0;//当前时间
							//如果状态为暂停或者播放
							if(status == Constanly.STATUS_PAUSE || status == Constanly.STATUS_PLAY){
								duration = mp.getDuration();
								current = mp.getCurrentPosition();
								Intent intent = new Intent(Constanly.UPDATE_UI);
								intent.putExtra("status", Constanly.PROGRESS_GO);
								intent.putExtra("duration", duration);
								intent.putExtra("current", current);
								//广播Intent
								context.sendBroadcast(intent);
							}
						}
					};
				}.start();
			}else
			{
				//如果是暂停后播放,直接继续播放即可
				mp.start();
			}
			status = Constanly.STATUS_PLAY;
			break;
			
		case Constanly.COMMAND_PAUSE:
			status = Constanly.STATUS_PAUSE;
			mp.pause();
			break;
		case Constanly.COMMADN_STOP:
			status = Constanly.STATUS_STOP;
			mp.stop();
			break;
		}
		updateUI(context);
	}

	protected void updateUI(Context context) {
		Intent intent = new Intent(Constanly.UPDATE_UI);
		intent.putExtra("status", status);
		context.sendBroadcast(intent);
	}
}

在命令广播接收类中,判断命令,使用path是否为空来判断是暂停后播放,还是停止状态后播放。在这个类中主要实现播放音乐,同时更改当前状态发送至UI更新广播类中,

给出UI广播接收类:

package com.example.sample5_11tdw;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;

public class UpateUIReceiver extends BroadcastReceiver{

	private Activity ac;
	public int status;
	public UpateUIReceiver(Activity ac) {
		this.ac = ac;
	}
	@Override
	public void onReceive(Context context, Intent intent) {
		ImageButton pauseButton = (ImageButton) ac.findViewById(R.id.pause);
		ProgressBar pb = (ProgressBar) ac.findViewById(R.id.pb);
		
		int tempStatus = intent.getIntExtra("status", -1);
		switch (tempStatus) {
		case Constanly.STATUS_PLAY:
			pauseButton.setImageResource(R.drawable.pause);
			status = tempStatus;
			break;
		case Constanly.STATUS_PAUSE:
			pauseButton.setImageResource(R.drawable.play);
			status = tempStatus;
			break;
		case Constanly.STATUS_STOP:
			pb.setProgress(0);
			pauseButton.setImageResource(R.drawable.play);
			status = tempStatus;
			break;
		case Constanly.PROGRESS_GO:
			
			int duration = intent.getIntExtra("duration", 0);
			int current = intent.getIntExtra("current", 0);
			pb.setMax(duration);
			pb.setProgress(current);
			
			TextView tv = (TextView) ac.findViewById(R.id.tv);
			tv.setText(convertToMinute(current)+"/"+convertToMinute(duration));
			break;
		}
	}
	
	private String convertToMinute(int value) {//得到的是毫秒值,返回格式0:00
		int second = value / 1000;
		int minute = second / 60;
		second = second % 60;
		String minStr = String.valueOf(minute);
		String secStr = String.valueOf(second);
		return minStr+":"+(second>9?second:"0"+second);
	}
}

在这个广播接收类中主要实现UI的更新。

一个常量类:

package com.example.sample5_11tdw;

public class Constanly {//常量类

	//播放命令
	public final static int COMMAND_PLAY = 0;
	//暂停命令
	public final static int COMMAND_PAUSE = 1;
	//停止命令
	public final static int COMMADN_STOP = 2;
	
	
	
	//播放状态
	public final static int STATUS_PLAY = 3;
	//暂停状态
	public final static int STATUS_PAUSE = 4;
	//停止状态
	public final static int STATUS_STOP = 5;
	
	
	//状态更新常量
	public final static int PROGRESS_GO = 6;
	
	
	//更新界面
	public final static String UPDATE_UI = "UPDATE_UI";
	//音乐控制
	public final static String MUSIC_CONTROL = "MUSIC_CONTROL";
}


给出service服务类:

package com.bn.chap5.no;

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.os.IBinder;

//后台播放的Service类
public class MyMusicPlayerService extends Service {
	CommandReceiver cr;//命令Intent接收者对象引用
	
	@Override
	public IBinder onBind(Intent intent) 
	{//因为本例用不到Bind功能,因此直接返回null
		return null;
	}

	@Override
	public void onCreate()
	{
		super.onCreate();
		
		//创建命令Intent接收者对象
		cr=new CommandReceiver();		
		//创建媒体播放器对象
		cr.mp=new MediaPlayer();
		//初始状态为停止状态
		cr.status=Constant.STATUS_STOP;
		
		//动态注册接收播放、暂停、停止命令Intent的CommandReceiver
		IntentFilter filter=new IntentFilter();
		filter.addAction(Constant.MUSIC_CONTROL);
		this.registerReceiver(cr, filter);		
	}
	
	@Override
	public void onDestroy()
	{
		super.onDestroy();
		//取消注册接收播放、暂停、停止命令Intent的CommandReceiver
		this.unregisterReceiver(cr);
		//释放播放器对象
		cr.mp.release();
	}
	
	@Override
	public void onStart(Intent intent, int id)
	{		
		//更新界面状态
		cr.updateUI(this.getApplicationContext());
	}
}

记得在清单文件需要注册service类:

 <service android:name=".MyMusicService" android:process=":remote"></service>


代码链接:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值