实验目标和实验内容: 1、掌握服务的基本概念,能编写服务过程并进行调用; 2、掌握广播的基本概念,能实现广播通信。 3、需实现的具体功能为: 短信到来时自动产生的系统广播→激活音乐播放服务程序→活动组件程序使得停止按钮可用。
实验结果:(实验小结与结果截图)
4、功能说明与核心代码
在类微信app的一个fragment上实现一个简易的播放器,有歌曲的封面,显示歌名,歌手名,三个button播放、上一首、下一首。
Tab02.xml文件布局声明
MusicBoxFragment.java源码
实现接口OnClickListener,然后生成重写函数onclick生成大致的框架
public class MusicBoxFragment extends Fragment implements View.OnClickListener {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
TextView title, author;
ImageButton play, stop;
ImageButton pre, next;
ImageView cover;
ActivityReceiver activityReceiver;
public static final String CTL_ACTION =
"org.ad.action.CTL_ACTION";
public static final String UPDATE_ACTION =
"org.ad.action.UPDATE_ACTION";
int status = 0x11;
String[] titleStrs = new String[] { "爱蜜莉", "Rollin' On", "揪心的玩笑与漫长的白日梦" };
String[] authorStrs = new String[] { "回春丹", "椅子乐队", "万能青年旅店" };
Integer[] covers = new Integer[]{R.drawable.hcd, R.drawable.yz, R.drawable.wq};
public MusicBoxFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static MusicBoxFragment newInstance(String param1, String param2) {
MusicBoxFragment fragment = new MusicBoxFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onClick(View view) {
Intent intent = new Intent(CTL_ACTION);
switch (view.getId()) {
case R.id.play:
intent.putExtra("control", 1);
break;
case R.id.stop:
intent.putExtra("control", 2);
break;
case R.id.pre:
intent.putExtra("control", 3);
break;
case R.id.next:
intent.putExtra("control", 4);
break;
}
getActivity().sendBroadcast(intent);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
activityReceiver = new ActivityReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(UPDATE_ACTION);
getActivity().getApplicationContext().registerReceiver(activityReceiver, filter);
Intent intent = new Intent(getActivity(), MusicService.class);
getActivity().startService(intent);
}
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]);
cover.setImageResource(covers[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 View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab02, container, false);
play = view.findViewById(R.id.play);
stop = view.findViewById(R.id.stop);
title = view.findViewById(R.id.title);
author = view.findViewById(R.id.author);
cover = view.findViewById(R.id.cover);
pre = view.findViewById(R.id.pre);
next = view.findViewById(R.id.next);
play.setOnClickListener(this);
stop.setOnClickListener(this);
pre.setOnClickListener(this);
next.setOnClickListener(this);
return view;
}
} MusicService.java的源码 public class MusicService extends Service { MyReceiver serviceReceiver; AssetManager am; String[] musics = new String[]{"蜜莉.mp3,Rollin' On.mp3,揪心的玩笑与漫长的白日梦.mp3"}; MediaPlayer mPlayer; int status = 0x11; int current = 0;
@Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); am = getAssets(); serviceReceiver = new MyReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(MusicBoxFragment.CTL_ACTION); registerReceiver(serviceReceiver, filter); mPlayer = new MediaPlayer(); mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { current++; if (current >= 4) current = 0; Intent sendIntent = new Intent(MusicBoxFragment.UPDATE_ACTION); sendIntent.putExtra("current", current); sendBroadcast(sendIntent); prepareAndPlay(musics[current]); } }); } public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(final 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; } case 3: current--; if (current < 0) current = 0; prepareAndPlay(musics[current]); case 4: current++; if (current > musics.length - 1) current = 0; prepareAndPlay(musics[current]); } Intent sendIntent = new Intent(MusicBoxFragment.UPDATE_ACTION); sendIntent.putExtra("update", status); sendIntent.putExtra("current", current); sendBroadcast(sendIntent); } } private void prepareAndPlay(String music) { try { AssetFileDescriptor afd = am.openFd(music); mPlayer.reset(); mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); mPlayer.prepare(); mPlayer.start(); } catch (IOException e) { e.printStackTrace(); } } } 还有很重要的一点要在AndroidManife.xml上声明一定要绑定服务.MusicService,绑定后,service组件才会起到作用
5、结果截图
6、实验小结 Broadcast(广播机制) 是一种广泛运用的应用程序之间 传输信息 的机制,而BroadcastReceiver(广播接收器) 则是用于接收来自系统和应用的广播对并其进行响应的组件,Android中我们要发送的广播内容是一个Intent,这个Intent中可以携带我们要传送的数据。所以音乐盒一般用广播的方式实现。