当收到自定义广播时播放音乐

想要在收到广播的时候播放音乐,大体分为两个步骤。首先要接收到广播,然后通过服务播放音乐。

01 广播

Android 应用与 Android 系统和其他 Android 应用之间可以相互收发广播消息,这与发布-订阅设计模式相似。这些广播会在所关注的事件发生时发送。举例来说,Android 系统会在发生各种系统事件时发送广播,例如系统启动或设备开始充电时。再比如,应用可以发送自定义广播来通知其他应用它们可能感兴趣的事件(例如,一些新数据已下载)。

接收广播有两种方式,一种是使用静态文件注册广播接收器、另外一种是动态的注册广播接收器。此处我们将分别使用两种方法介绍如何接收系统广播和自定义广播。

系统广播

我们将使用静态注册广播接收器的方式来接收接收短信产生的系统广播。

  1. 再Manifests.xml文件中声明Receiver

    <receiver
        android:name=".SmsReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
        </intent-filter>
    </receiver>
    
  2. 创建 BroadcastReceiver 子类并实现 onReceive(Context, Intent)

    package xyz.retrove.androidcrouse2;
       
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
       
    public class SmsReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
       
            Intent serviceIntent = new Intent(context, MyService.class);
            //在广播组件里,通过上下文对象启动音乐播放服务组件
            context.startService(serviceIntent);
       
            //新建调用Activity组件的意图
            Intent activityIntent = new Intent(context, MainActivity.class);
            activityIntent.putExtra("iscast", true);  //携带数据
            //新建栈用来存放被启动的Activity(当已经存在时,只做移动处理)
            activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            //在广播组件里,通过上下文对象启动Activity组件
            context.startActivity(activityIntent);
        }
    }
    

这样,我们在收到短信的时候就会触发SmsReceiver中的onReceive()方法。在上面的代码中,我们在onReceive()中启动了播放音乐的服务,在后面的文章会有详细代码。

注意:在Android中,要获取到接收短信的系统广播,应用必须要有相关的权限。

if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED){
    ActivityCompat.requestPermissions(this,new String[]{"android.permission.RECEIVE_SMS"},1);
}

自定义广播

此处我们使用动态注册的方式声明广播接收器。但首先,我们需要先创建一个自定义广播。

创建自定义广播

在这里我们创建了一个自定义广播,其中还附有两个数据,分别是要播放的歌名和歌手(目前是hard code在代码中)。

Intent myintent = new Intent("com.example.broadcast.MY_BROADCAST");
Bundle  bundle = new Bundle();
bundle.putString("data1", "Higher Power");
bundle.putString("data2", "COLDPLAY");
myintent.putExtras(bundle);
sendBroadcast(myintent);

我们将这段代码嵌入到按钮的ClickListener中,使得按下按钮后就会发出该广播。

image-20210511213702845

接收自定义广播

  1. 创建 BroadcastReceiver 的实例

    private BroadcastReceiver myReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle mybundle =  intent.getExtras();
            String str1 = mybundle.getString("data1");
            String str2 = mybundle.getString("data2");
            Toast.makeText(context, str1+" " +str2,Toast.LENGTH_LONG).show();
            Intent serviceIntent = new Intent(context, MyService.class);
            //在广播组件里,通过上下文对象启动音乐播放服务组件
            context.startService(serviceIntent);
       
            //新建调用Activity组件的意图
            Intent activityIntent = new Intent(context, MainActivity.class);
            activityIntent.putExtra("iscast", true);  //携带数据
            //新建栈用来存放被启动的Activity(当已经存在时,只做移动处理)
            activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            //在广播组件里,通过上下文对象启动Activity组件
            context.startActivity(activityIntent);
        }
    };
    
  2. 创建 IntentFilter 并调用 registerReceiver(BroadcastReceiver, IntentFilter) 来注册接收器

    IntentFilter myintentfliter = new IntentFilter();
    myintentfliter.addAction("com.example.broadcast.MY_BROADCAST");
    registerReceiver(myReceiver, myintentfliter);
    

02 播放音乐的服务

package xyz.retrove.androidcrouse2;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.media.MediaPlayer;

public class MyService extends Service {

    private MediaPlayer mediaPlayer = new MediaPlayer();
    private MyBinder binder;
    private BroadcastReceiver receiver;
    private static final String TAG = "MediaService";


    @Override
    public void onCreate() {
        super.onCreate();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        initMediaPlayerFile();
        playMusic();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        mediaPlayer.stop();
        super.onDestroy();
    }


    /**
     * 播放音乐
     */
    public void playMusic() {
        if (!mediaPlayer.isPlaying()) {
            //如果还没开始播放,就开始
            mediaPlayer.start();
        }
    }

    /**
     * 暂停播放
     */
    public void pauseMusic() {
        if (mediaPlayer.isPlaying()) {
            //如果还没开始播放,就开始
            mediaPlayer.pause();
        }
    }

    /**
     * reset
     */
    public void resetMusic() {
        if (!mediaPlayer.isPlaying()) {
            //如果还没开始播放,就开始
            mediaPlayer.reset();
            //initMediaPlayerFile();
        }
    }

    /**
     * 关闭播放器
     */
    public void closeMedia() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }

    public void initMediaPlayerFile(){
        mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.music1);
    }


}

03 最终效果及源码

点击按钮后即会显示Toast信息并开始播放音乐:

image-20210511214156862

源码:https://github.com/Retr0ve/AndroidCrouse2