从一个音乐播放器来理解android的Service组件和BroadcastReceiver
- 前言:很久以前写过一个音乐播放器,采用Service组件实现后台播放,BroadcastReceiver实现消息传递。播放器源码在此:简陋音乐播放器。
- MusicBox.java
package org.crazyit.broadcast;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
public class MusicBox extends Activity implements OnClickListener {
TextView title, author;
ImageButton play, stop;
public AudioManager mAudioManager = null;
public static SeekBar audioSeekBar = null;
public SeekBar audioVolume = null;
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[] authorStrs = new String[] { "未知艺术家", "周蕙", "伍佰" };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
play = (ImageButton) this.findViewById(R.id.play);
stop = (ImageButton) this.findViewById(R.id.stop);
title = (TextView) findViewById(R.id.title);
author = (TextView) findViewById(R.id.author);
audioVolume = (SeekBar) findViewById(R.id.seekBar2);
audioSeekBar = (SeekBar) findViewById(R.id.seekBar1);
play.setOnClickListener(this);
stop.setOnClickListener(this);
audioSeekBar.setOnSeekBarChangeListener(new SeekBarChangeEvent());
if (MusicService.mPlayer != null) {
MusicBox.audioSeekBar.setMax(MusicService.mPlayer.getDuration());
audioSeekBar.setProgress(MusicService.mPlayer.getCurrentPosition());
}
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
audioVolume.setProgress(mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC));
audioVolume.setOnSeekBarChangeListener(new AudioVolumeChangeEvent());
activityReceiver = new ActivityReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(UPDATE_ACTION);
registerReceiver(activityReceiver, filter);
Intent intent = new Intent(this, MusicService.class);
startService(intent);
}
class AudioVolumeChangeEvent implements SeekBar.OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress,
0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
MusicService.mPlayer.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
MusicService.mPlayer.pause();
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
MusicService.mPlayer.start();
}
}
public class ActivityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int update = intent.getIntExtra("update", -1);
int current = intent.getIntExtra("current", -1);
if (current >= 0) {
title.setText(titleStrs[current]);
author.setText(authorStrs[current]);
}
switch (update) {
case 0x11:
play.setImageResource(R.drawable.play);
status = 0x11;
break;
case 0x12:
play.setImageResource(R.drawable.pause);
status = 0x12;
break;
case 0x13:
play.setImageResource(R.drawable.play);
status = 0x13;
break;
}
}
}
@Override
public void onClick(View source) {
Intent intent = new Intent("org.crazyit.action.CTL_ACTION");
switch (source.getId()) {
case R.id.play:
intent.putExtra("control", 1);
break;
case R.id.stop:
intent.putExtra("control", 2);
break;
}
sendBroadcast(intent);
}
}
package org.crazyit.broadcast;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
public class MusicBox extends Activity implements OnClickListener {
TextView title, author;
ImageButton play, stop;
public AudioManager mAudioManager = null;
public static SeekBar audioSeekBar = null;
public SeekBar audioVolume = null;
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[] authorStrs = new String[] { "未知艺术家", "周蕙", "伍佰" };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
play = (ImageButton) this.findViewById(R.id.play);
stop = (ImageButton) this.findViewById(R.id.stop);
title = (TextView) findViewById(R.id.title);
author = (TextView) findViewById(R.id.author);
audioVolume = (SeekBar) findViewById(R.id.seekBar2);
audioSeekBar = (SeekBar) findViewById(R.id.seekBar1);
play.setOnClickListener(this);
stop.setOnClickListener(this);
audioSeekBar.setOnSeekBarChangeListener(new SeekBarChangeEvent());
if (MusicService.mPlayer != null) {
MusicBox.audioSeekBar.setMax(MusicService.mPlayer.getDuration());
audioSeekBar.setProgress(MusicService.mPlayer.getCurrentPosition());
}
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
audioVolume.setProgress(mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC));
audioVolume.setOnSeekBarChangeListener(new AudioVolumeChangeEvent());
activityReceiver = new ActivityReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(UPDATE_ACTION);
registerReceiver(activityReceiver, filter);
Intent intent = new Intent(this, MusicService.class);
startService(intent);
}
class AudioVolumeChangeEvent implements SeekBar.OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress,
0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
MusicService.mPlayer.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
MusicService.mPlayer.pause();
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
MusicService.mPlayer.start();
}
}
public class ActivityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int update = intent.getIntExtra("update", -1);
int current = intent.getIntExtra("current", -1);
if (current >= 0) {
title.setText(titleStrs[current]);
author.setText(authorStrs[current]);
}
switch (update) {
case 0x11:
play.setImageResource(R.drawable.play);
status = 0x11;
break;
case 0x12:
play.setImageResource(R.drawable.pause);
status = 0x12;
break;
case 0x13:
play.setImageResource(R.drawable.play);
status = 0x13;
break;
}
}
}
@Override
public void onClick(View source) {
Intent intent = new Intent("org.crazyit.action.CTL_ACTION");
switch (source.getId()) {
case R.id.play:
intent.putExtra("control", 1);
break;
case R.id.stop:
intent.putExtra("control", 2);
break;
}
sendBroadcast(intent);
}
}