运用Broadcast实现service与activity的通信
做到了这一步,现在的播放器应该可以显示歌曲列表,能够点击并播放音乐了哈,但是上面的按钮一个都不能点啊有没有,一旦放起来停都停不下来,不要着急,这一篇博客将介绍怎么将activity上的按钮都派上用场.
前面介绍过了,播放歌曲是在一个service中进行的,而按钮在activity和fragment上,怎么才能让它们联系起来呢?这就要用到安卓的另外一个四大组件之一----Broadcast,通常翻译为广播(感觉又是怪怪的样子),Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的 Broadcast进行过滤接受并响应的一类组件。这篇将介绍如何实现service和activity的通信.
发送广播的方式很简单,只需要新建一个Intent,里面存放一些需要传出去的信息即可,例如
- Intent intent_to_activity = new Intent("color:#ff9966;">"com.dada.communication.RECEIVER");
- intent_to_activity.putExtra("title", intent.getStringExtra("title"));
- intent_to_activity.putExtra("artist", intent.getStringExtra("artist"));
- intent_to_activity.putExtra("album", intent.getStringExtra("album"));
- intent_to_activity.putExtra("album_id", intent.getLongExtra("album_id", 0));
这样就把信息存放在了intent_to_activity中了,之后再用一句话,sendBroadcast(intent_to_activity)将这个包含信息的intent发送出去,发送广播的工作就已经做完啦,发出广播之后,还需要接收这个消息,这里需要实现的是activity和service的通信,故一边发,另外一边接收,上面的代码是写在service中的,故接收器应写在activity中.
定义广播的接收器,有三个步骤,
第一步: 定义一个自定义Receiver类,需要继承Broadcast类,其中写入收到广播之后,需要执行的代码,例如:
- private class MsgReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- music_info_textView = (TextView)findViewById(R.id.music_info_textView);
- singer_info_textView = (TextView)findViewById(R.id.singer_info_textView);
-
- music_info_textView.setText(intent.getStringExtra("title"));
- singer_info_textView.setText(intent.getStringExtra("artist"));
-
- }
- }
第二步: 实例化这个类,并创建一个IntentFilter,这个相当于一个广播的过滤器,对其进行操作,可以过滤出自己想要监听的广播.
- IntentFilter intentMsgFilter = new IntentFilter();
第三步: 对IntentFilter操作,并将其与第一步定义的接收器绑定在一起.
- intentMsgFilter.addAction("color:#ff6666;">"com.example.communication.RECEIVER");
- registerReceiver(msgReceiver,intentMsgFilter);
到这里,广播的收发就能进行了,是不是比较容易.下面就给出MainActivity.java和PlayerService.java的代码,红色部分为基于上一篇的改动,里面主要就是实现了播放与暂停键的相应,歌曲名和艺术家名的显示,还有进度条的更新.
MainActivity.java
- "color:#ff0000;">这个方法是重写了activity里自带的方法onStart()
- "color:#ff0000;">里面要带上super.onStart();不然会报错的
- "color:#ff0000;">*/
- "color:#ff0000;"> @Override
- protected void onStart(){
-
- super.onStart();
- IntentFilter intentMsgFilter = new IntentFilter();
- IntentFilter intentBarFilter = new IntentFilter();
-
-
- intentMsgFilter.addAction("com.example.communication.RECEIVER");
- registerReceiver(msgReceiver,intentMsgFilter);
-
- intentBarFilter.addAction("com.example.communication.BAR");
- registerReceiver(barReceiver,intentBarFilter);
- }
-
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- music_position = 0;
- "color:#ff0000;"> current_position = 0;
- finder = new FindSongs();
-
- "color:#ff0000;"> msgReceiver = new MsgReceiver();
- barReceiver = new BarReceiver();
-
- mp3Infos = finder.getMp3Infos(getContentResolver());
-
- "color:#ff0000;"> intent_to_service = new Intent("com.example.communication.PLAY");
-
- seek_bar = (SeekBar)findViewById(R.id.process_bar);
- play_button = (ImageButton)findViewById(R.id.play_button);
- play_button.setImageResource(R.drawable.play_photo);
- "color:#ff0000;"> play_button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if(isPause){
- isPause = false;
- play_button.setImageResource(R.drawable.pause_photo);
- }
- else{
- isPause = true;
- play_button.setImageResource(R.drawable.play_photo);
- }
- "color:#ff0000;">将音乐播放到了的当前位置和当前的状态
- "color:#ff0000;">以广播的形式发送给service
- "color:#ff0000;">来让service可以接着刚才暂停的位置开始播放
- "color:#ff0000;"> intent_to_service.putExtra("position",current_position);
- intent_to_service.putExtra("isPause",isPause);
- sendBroadcast(intent_to_service);
- }
- });
-
- mainFragment = new MainFragment();
- fragmentManager = getFragmentManager();
- fragmentTransaction = fragmentManager.beginTransaction();
- fragmentTransaction.replace(R.id.fragment_layout, mainFragment).commit();
- }
-
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
-
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
-
-
-
- int id = item.getItemId();
-
-
- if (id == R.id.action_settings) {
- return true;
- }
-
- return super.onOptionsItemSelected(item);
- }
-
- private void initService(int position) {
- music_position = position;
- Mp3Info mp3Info = mp3Infos.get(position);
-
- "color:#ff0000;"> seek_bar.setMax((int)mp3Info.getDuration());
-
-
-
-
-
-
-
-
-
-
-
-
-
- Intent intent = new Intent("com.example.communication.MSG_ACTION");
- play_button.setImageResource(R.drawable.pause_photo);
- intent.putExtra("url", mp3Info.getUrl());
- intent.putExtra("title", mp3Info.getTitle());
- intent.putExtra("artist", mp3Info.getArtist());
- intent.putExtra("album", mp3Info.getAlbum());
- intent.putExtra("album_id", mp3Info.getAlbum_id());
- intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG);
- intent.setClass(MainActivity.this, PlayerService.class);
- startService(intent);
- }
-
- "color:#ff0000;"> private class MsgReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- music_info_textView = (TextView)findViewById(R.id.music_info_textView);
- singer_info_textView = (TextView)findViewById(R.id.singer_info_textView);
-
- "color:#ff0000;">从接收到的广播的intent中取出发送过来的信息
- "color:#ff0000;">这里是取出了歌曲名和艺术家名
- "color:#ff0000;"> music_info_textView.setText(intent.getStringExtra("title"));
- singer_info_textView.setText(intent.getStringExtra("artist"));
-
- }
- }
-
- private class BarReceiver extends BroadcastReceiver{
- @Override
- public void onReceive(Context context, Intent intent) {
- "color:#ff0000;">取出后,更新进度条当前的位置
- "color:#ff0000;">*/
- current_position = intent.getIntExtra("position",0);
- seek_bar.setProgress(current_position);
- }
- }
- }
PlayerService.java
- package com.example.dada.myapplication;
-
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.app.Service;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.media.MediaPlayer;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Looper;
- import android.os.Message;
- import android.view.animation.AnimationUtils;
- import android.widget.RemoteViews;
-
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
-
-
- public class PlayerService extends Service implements AppConstant {
-
- private int current_position;
-
- private String musicPath;
- private String music_artist;
- private String music_title;
- private String notification_msg;
-
- private boolean isPause = true;
- private boolean isChangToNext;
-
- "color:#ff0000;"> private PlayReceiver playReceiver;
-
- public static MediaPlayer mediaPlayer = new MediaPlayer();
-
- "color:#ff0000;"> private Intent intent_to_activity = new Intent("com.example.communication.RECEIVER");
- private Intent intent_to_progressBar = new Intent("com.example.communication.BAR");
-
"code" class="java" style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">"color:#ff0000;"> "color: rgb(255, 0, 0); font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">/*这里运用到了Handler对各种消息的处理,主要是用它来更新UI
- "font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;color:#ff0000;"> 在下面代码的自定义广播接收器类中,收到消息后,会给这个myHandler发送消息
- "font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;color:#ff0000;">再由这个myHandler做统一的处理
- "color: rgb(255, 0, 0); font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">*/
- "color:#ff0000;"> private Handler myHandler = new Handler() {
- "color:#ff0000;">
- public void handleMessage(Message msg) {
- if (msg.what == PlayerMsg.PLAY_MSG) {
- current_position = mediaPlayer.getCurrentPosition();
- intent_to_progressBar.putExtra("position", current_position);
- sendBroadcast(intent_to_progressBar);
- myHandler.sendEmptyMessageDelayed(PlayerMsg.PLAY_MSG, 1000);
- }
- if (msg.what == PlayerMsg.PAUSE) {
- stopMusic();
- }
- }
- };
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- notification_msg = null;
- "color:#ff0000;">这里就是前面讲到的接收广播的三部曲
- "color:#ff0000;">*/
- "color:#ff0000;">playReceiver = new PlayReceiver();
- IntentFilter intentPlayFilter = new IntentFilter();
- intentPlayFilter.addAction("com.example.communication.PLAY");
- registerReceiver(playReceiver, intentPlayFilter);
-
- try {
- int msg = intent.getIntExtra("MSG", 0);
- musicPath = intent.getStringExtra("url");
- "color:#ff0000;">SendBroadcastToActivity(intent);
-
- if (msg == AppConstant.PlayerMsg.PLAY_MSG) {
- "color:#ff0000;">向myHandler发送消息,由myHandler做出处理
- "color:#ff0000;">*/
- "color:#ff0000;"> myHandler.sendEmptyMessage(PlayerMsg.PLAY_MSG);
- playMusic(0);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return 0;
- }
-
- private void playMusic(int position) {
- try {
- mediaPlayer.reset();
- mediaPlayer.setDataSource(musicPath);
- mediaPlayer.prepare();
- mediaPlayer.setOnPreparedListener(new MyPreparedListener(position));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- private class MyPreparedListener implements MediaPlayer.OnPreparedListener {
-
- private int position;
-
- public MyPreparedListener(int position) {
- this.position = position;
- }
-
- public void onPrepared(MediaPlayer mp) {
- if (position > 0)
- mediaPlayer.seekTo(position);
- mediaPlayer.start();
- }
- }
-
- private void stopMusic() {
- if (mediaPlayer != null) {
- mediaPlayer.pause();
- }
- }
-
- public void onDestory() {
- if (mediaPlayer != null) {
- mediaPlayer.stop();
- mediaPlayer.release();
- }
- }
-
- "color:#ff0000;"> private void SendBroadcastToActivity(Intent intent) {
-
- music_title = intent.getStringExtra("title");
- music_artist = intent.getStringExtra("artist");
- intent_to_activity.putExtra("title", intent.getStringExtra("title"));
- intent_to_activity.putExtra("artist", intent.getStringExtra("artist"));
- intent_to_activity.putExtra("album", intent.getStringExtra("album"));
- intent_to_activity.putExtra("album_id", intent.getLongExtra("album_id", 0));
- sendBroadcast(intent_to_activity);
- }
-
- private class PlayReceiver extends BroadcastReceiver {
-
- public PlayReceiver() {
- super();
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
-
- isPause = intent.getBooleanExtra("isPause", true);
- isChangToNext = intent.getBooleanExtra("isChangeToNext", false);
-
- if (isPause) {
- myHandler.sendEmptyMessage(PlayerMsg.PAUSE);
- } else {
- current_position = intent.getIntExtra("position", 0);
- playMusic(current_position);
- myHandler.sendEmptyMessage(PlayerMsg.PLAY_MSG);
- }
- }
- }
-
- }
上面好长好长的代码,实现的就是能暂停和播放,进度条能显示播放进度,activity能显示歌曲信息,其中包含了两个Broadcast的收发,一个handler的应用.广播在android开发中用的还是比较多的,感觉也是比较好用的哈.