`
gryphone
  • 浏览: 433686 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

音乐播放器widget 前传 - 播放器的构建

阅读更多

音乐播放器widget

 

[功能]

有人可能会问:又不是写小说 分什么前传后传啊

 

因为音乐播放器widget 不仅涉及到widget 而且音乐播放器有有一些特别的设定 而且在一篇里面都讲会内容太多 而且比较杂乱 所以打算分开讲解

 

前传:音乐播放器

后传:widget

 

 

所以这次会以 音乐播放器 为主  顺便包括一些与widget功能有关的东西

 

 

又因为主要的目的还是widget 所以音乐播放功能会比较少 只要下面功能:

写道
1. 播放/暂停
2. 换曲 即 下一曲

 

大家可以自己扩展之!

 

 

[代码 步骤]

 

1. 准备一下下面用到的字符串常量

public class MusicPlayerHelper {
	
	//供 MusicPlayerService 接收Broadcast用 主要接受来自于 MusicPlayerActivity 的消息
	public final static String Broadcast_MusicPlayerService = "Broadcast_MusicPlayerService";
	
	//供 MusicPlayerWidget 接收Broadcast用 主要接受来自于 MusicPlayerService 的消息
	public final static String Broadcast_MusicPlayerWidget = "Broadcast_MusicPlayerWidget";
	
	//供 MusicPlayerService 接收MusicPlayerWidget换曲用 主要接受来自于 MusicPlayerService 的消息
	public final static String Broadcast_MusicPlayerService_Next = "Broadcast_MusicPlayerService_Next";
	
	
	//用于 播放控制 消息 
	public final static String Message_MusicPlayerService_CMD = "Message_MusicPlayerService_CMD";
	
	public final static String Message_MusicPlayerService_Next = "Message_MusicPlayerService_Next";
	public final static String Message_MusicPlayer_Text = "Message_MusicPlayer_Text";
	
	
	//2首歌曲 一个供开始播放用 一个供下一曲
	public final static String MUSIC1 = "/sdcard/GuoHuo.mp3";
	public final static String MUSIC2 = "/sdcard/WelcomeToBeijing.mp3";
}

 

 

 

 

 

2. 准备播放器界面 只要2个Button 一个用于播放控制 一个用于换曲

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<Button  
	android:id="@+id/cmd"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="start/pause!"
    />
<Button  
	android:id="@+id/next"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Next!"
    />
</LinearLayout>

 

 

3. 分别给2个Button 注册OnClickListener()

public class MusicPlayerActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        startService(new Intent(this,MusicPlayerService.class));
        
        
        findViewById(R.id.cmd).setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				sendMusicPlayerMessageCmd();
			}
        	
        });
        
        
        findViewById(R.id.next).setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				sendMusicPlayerMessageNext();
			}
        	
        });
    }
    
    
    public void sendMusicPlayerMessageCmd(){
    	Intent i = new Intent(MusicPlayerHelper.Broadcast_MusicPlayerService);
    	
    	Bundle b = new Bundle();
    	b.putString(MusicPlayerHelper.Message_MusicPlayerService_CMD, "NA");
    	
    	i.putExtras(b);
    	sendBroadcast(i);
    }
    
    public void sendMusicPlayerMessageNext(){
    	Intent i = new Intent(MusicPlayerHelper.Broadcast_MusicPlayerService);
    	
    	Bundle b = new Bundle();
    	b.putString(MusicPlayerHelper.Message_MusicPlayerService_Next, "NA");
    	
    	i.putExtras(b);
    	sendBroadcast(i);
    }
}

 

 

 4. MusicPlayerService 里的 播放/暂停 控制 及 换曲 功能

//播放指定音乐
	public void playMusic(String s){
		mp.reset();
		
		try {
			mp.setDataSource(s);
			
			mp.prepare();
			
			mp.start();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void sendMusicText(String s){
		Intent i = new Intent(MusicPlayerHelper.Broadcast_MusicPlayerWidget);
    	
    	Bundle b = new Bundle();
    	b.putString(MusicPlayerHelper.Message_MusicPlayer_Text, s);
    	
    	i.putExtras(b);
    	sendBroadcast(i);
	}

 

 

5. MusicPlayerService 的 BroadcastReceiver 实现 及 注册

 

- 实现

//Broadcast 既接受来自MusicPlayerActivity的Broadcast 也接受来自MusicPlayerWidget的Broadcast
	public class MusicPlayerListenerHelper extends BroadcastReceiver {
		Context context;
		
		MusicPlayerListenerHelper listener;
		//construct 
		public MusicPlayerListenerHelper(Context c){
			context = c;
			
			//to instance it
			listener = this;
		}
		
		public void registerAction(String action){
			IntentFilter filter = new IntentFilter();
			filter.addAction(action);
			
			context.registerReceiver(listener,filter);
		}
		
		
		@Override
		public void onReceive(Context arg0, Intent arg1) {
			// TODO Auto-generated method stub
			
			//对接收到的Broadcast进行判断 是MusicPlayerActivity还是MusicPlayerWidget 通过Intent.getActon()
			if(arg1.getAction().endsWith(MusicPlayerHelper.Broadcast_MusicPlayerService)){
				Bundle b = arg1.getExtras(); 
				
				if(b.containsKey(MusicPlayerHelper.Message_MusicPlayerService_Next)){
					playMusic(MusicPlayerHelper.MUSIC2);
				}
				else if(b.containsKey(MusicPlayerHelper.Message_MusicPlayerService_CMD)){
					switchMusic();
				}
			}
			else if(arg1.getAction().endsWith(MusicPlayerHelper.Broadcast_MusicPlayerService_Next)){
				playMusic(MusicPlayerHelper.MUSIC2);
				sendMusicText("Hello to MusicPlayerWidget!");
			}
			
		}
		
	}

 

 

- 注册

//注册BroadcastReceiver 用于接受来自MusicPlayerActivity的消息
		MusicPlayerListenerHelper helper = new MusicPlayerListenerHelper(this);
		helper.registerAction(MusicPlayerHelper.Broadcast_MusicPlayerService);
		
		//注册BroadcastReceiver 用于接受来自MusicPlayerWidget的消息
		MusicPlayerListenerHelper nextHelper = new MusicPlayerListenerHelper(this);
		nextHelper.registerAction(MusicPlayerHelper.Broadcast_MusicPlayerService_Next);
		

 

 

写道
可能细心的人会奇怪 为什么要 new 2 次 因为:

[其他]
假如我们的BroadcastReceiver 要接受2种消息 即 MessageA & MessageB

普通的做法是:Bundle复用 然后通过Bundle.getString() 来区分是MessageA 还是 MessageB

如:
- 发送端:
Intent i = new Intent(“目的BroadcastReceiver的匹配字串”);

Bundle b = new Bundle();
b.putString(key, value);

i.putExtras(b);
sendBroadcast(i);

- 接收端
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub


Bundle b = arg1.getExtras();

if(b.containsKey(BroadcastColumn.MESSAGE_STRING)){
String string = b.getString(BroadcastColumn.MESSAGE_STRING);
Log.d("TAG",string);
}

}
写道
其实 Bundle 主要通过对应的""key" 来 加载 和 提取 数据 的

  

 

写道
但是上述办法在widget中却不行 现在也不知道原因 是bug 还是故意使然

那么我们的办法就是: 定义2个BroadcastReceiver 一个用于接收来自MusicPlayerActivity的Broadcast 一个接收来自于MusicPlayerWidget 的Broadcast 还有别的办法么? 有 那就是通过BroadcastReceiver复用

BroadcastReceiver复用 就是:让一个BroadcastReceiver 接收几个Broadcast 然后在通过Intent.getAction() 来区分开

所以 要new 2 次 理解这点很重要!
写道
其实道理和Bundle复用一样 只是这次借助于BroadcastReceiver的 Action 字串

  

 

 

6. 至此 我们播放器功能就完成了 下次将说道其widget有关的功能! let's go!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics