关闭

基于Service的播放器,Activity,Service,BroadcastReceiver综合使用

标签: broadcastreceiver音乐androidservice
285人阅读 评论(0) 收藏 举报
分类:

前言:闲着也是闲着,不如多学点东西


下面的程序开发了一个基于Service组件的音乐盒,程序的音乐将会由后台运行的Service组件负责播放,当后台的播放状态发生改变时,程序将会通过发生广播通知前台Activity更新界面;当用户单击前台Activity的界面按钮时,系统将通过发送广播通知后台Service来改变播放状态。

Activity界面代码如下:

package com.example.musicproject;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{

	private TextView title,author;
	private ImageButton play,stop;
	ActivityReceiver activityReceiver;
	public static final String CTL_ACTION="org.crazyit.action.CTL_ACTION";
	public static final String UPDATE_ACTION="org.crazyit.action.UPDATE_ACTION";
	//定义音乐的播放状态
	int status = 0x11;
	String[] titleStrs = new String[]{"心愿","约定","美丽"};
	String[] autorStrs = new String[]{"未知艺术照","作者1","作者2"};		
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		title = (TextView) findViewById(R.id.title);
		author = (TextView) findViewById(R.id.author);
		play = (ImageButton) findViewById(R.id.play);
		stop = (ImageButton) findViewById(R.id.stop);
		play.setOnClickListener(this);
		stop.setOnClickListener(this);
		
		//广播
		IntentFilter filter = new IntentFilter();
		filter.addAction(UPDATE_ACTION);
		registerReceiver(activityReceiver, filter);
		
		//服务
		Intent intent = new Intent(this,MusicService.class);
		startService(intent);
	}

	//自定义的BroadcastReceiver,负责监听从service传回来的广播
	public class ActivityReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			// 获取Intent中的update消息,update代表播放状态
			int update = intent.getIntExtra("update", -1);
			//获取Intent中的current消息,current代表正在播放的歌曲
			int current = intent.getIntExtra("current", -1);
			if(current>=0){
				title.setText(titleStrs[current]);
				author.setText(autorStrs[current]);
			}
			switch (update) {
			case 0x11:
				play.setImageResource(R.drawable.button_grey_play);
				status = 0x11;
				break;
				//进入播放
			case 0x12:
				play.setImageResource(R.drawable.gnome_session_suspend);
				status = 0x12;
				break;
				//进入暂停
			case 0x13:
				play.setImageResource(R.drawable.button_grey_play);
				status = 0x13;
				break;
			default:
				break;
			}
		}
		
	}

	@Override
	public void onClick(View v) {
		// 创建Intent
		Intent intent = new Intent("org.crazyit.action.CTL_ACTION");
		switch (v.getId()) {
		//按下播放、暂停按钮
		case R.id.play:
			intent.putExtra("contorl", 1);
			break;
		//按下停止按钮
		case R.id.stop:
			intent.putExtra("contorl", 2);
			break;
		default:
			break;
		}
		
	}
}


上面代码关键地方有2处。

1)在ActivityReceiver中,代码主要用于相应后台Service所发出的广播,该程序将会根据广播Intent里的消息来改变播放状态,并更新程序界面中按钮的图标;当正在播放时,显示暂停图标;当正在暂停时,显示播放图表。并根据传回来的current数据来更新title.author两个文本框所显示的文本------显示当前正在播放的歌曲的歌名和歌手。

2)第二段粗体代码则根据用户单击的按钮发送广播,发送广播时会把所按下的按钮的标识发送出来。发送的广播将激发后台Service的BroadcastReceiver,该BroadcastReceiver将会根据广播消息来改变播放状态。


与之对应收到是,该程序的后台Service也一样,他会在播放状态发生改变时对外发送广播;它也会采用BroadcastReceiver监听来自前台Activity所发出的广播。

package com.example.musicproject;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;

public class MusicService extends Service{

	MyReceiver serviceReceiver;
	AssetManager am;
	String[] musics = new String[]{"wish.mp3","promise.mp3","beautiful.mp3"};
	MediaPlayer mPlayer;
	//当前的状态,0x11表示没有播放,0x22表示正在播放,0x33表示暂停
	int status = 0x11;
	//记录当前正在播放的音乐
	int current = 0;
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		am = getAssets();
		//创建BroadcastReceiver
		serviceReceiver =new MyReceiver();
		//创建IntentFilter
		IntentFilter filter = new IntentFilter();
		filter.addAction(MainActivity.CTL_ACTION);
		registerReceiver(serviceReceiver, filter);
		//创建MediaPlayer
		mPlayer = new MediaPlayer();
		//为MediaPlayer播放完成事件绑定监听器
		mPlayer.setOnCompletionListener(new OnCompletionListener() {
			
			@Override
			public void onCompletion(MediaPlayer mp) {
				// TODO Auto-generated method stub
				current++;
				if(current >=3){
					current = 0; 
				}
				//发送广播通知Activity更改文本框
				Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
				sendIntent.putExtra("current", current);
				//发送广播,将被Activity组件中的BroadcastReceiver接收到
				sendBroadcast(sendIntent);
				//准备并播放音乐
				prepareAndPlay(musics[current]);
			}
		});
		super.onCreate();
	}
	
	private void prepareAndPlay(String music) {
		// TODO Auto-generated method stub
		try {
			//打开指定音乐文件
			AssetFileDescriptor afd = am.openFd(music);
			mPlayer.reset();
			//使用MediaPlayer加载指定的声音文件
			mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
			//准备声音
			mPlayer.prepare();
			//播放
			mPlayer.start();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	public class MyReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			int control = intent.getIntExtra("control", -1);
			switch (control) {
			case 1:
				//原来处于没有播放状态
				if(status == 0x11){
					prepareAndPlay(musics[current]);
					status = 0x12;
				}
				//原来处于播放状态
				else if(status == 0x12){
					//暂停
					mPlayer.pause();
					//改变为暂停状态
					status = 0x13;
				}
				//原来处于暂停状态
				else if(status == 0x13){
					//播放
					mPlayer.start();
					//改变状态
					status= 0x12;
				}
				break;
			case 2:
				//如果原来正在播放或者正在播放或者暂停状态
				if(status ==  0x12 || status == 0x13){
					//停止播放
					mPlayer.stop();
					status=0x11;
				}
				break;
			default:
				break;
			}
			//广播通知Activity更改图标,文本框
			Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
			sendIntent.putExtra("update", status);
			sendIntent.putExtra("current", current);
			//发送广播,将被Activity组件中的BroadcastReceiver接收到
			sendBroadcast(sendIntent);
		}
		
	}
}


在MyReceiver中的代码用于接收来自前台Activity所发出的广播,并根据广播的消息内容改变Service的播放状态,当播放状态改变时,该Service对外发送一条广播,广播消息将会被前台Activity接收,前台Activity将会根据广播消息去更新程序界面。

除此之外,为了让该程序能按顺序依次播放每首歌曲,程序为MediaPlayer增加了ONCompletionListener监听器,当MediaPlayer播放完成后将让它自动播放下一首歌曲。

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:56961次
    • 积分:1165
    • 等级:
    • 排名:千里之外
    • 原创:53篇
    • 转载:49篇
    • 译文:0篇
    • 评论:8条
    最新评论