概述
Broadcast Receiver
Broadcast Receiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。在Android系统中,在进程和进程之间,应用和应用之间,经常要进行数据的传递,Broadcast Receiver也可以作为应用之间,或者组件之间传递数据的机制。广播体现在方方面面,例如开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能。
然后广播的类型有:
普通广播:它对于多个接收者来说是完全异步的,每个接受者不需要等待就可以接收到广播,接收者之间无法相互影响,也无法终止广播;
有序广播:顾名思义,它只发送到优先级较高的接收者那里,然后再由其转播到优先级低的接收者那里,同时,优先级高的接收者可以终止这个广播。例如短信可以被拦截。
粘性广播:就是假如接收者这边没有启动,但是发出了广播,然后接收者这边才启动,但是接收者依然可以接收到这个广播。
广播接收者有两种注册方法,一种是程序动态注册,它的特点是当用来注册的Activity关掉后,广播也就失效了;另一种方法是在AndroidManifest文件中进行静态注册,静态注册不需要担心广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用
功能需求
利用BroadcastReceiver组件实现基本音乐播放器功能:上一曲下一曲切换、
播放、暂停,以及当前播放歌曲信息显示
实现
1.静态注册
(1)广播不会跟随Activity的生命周期的结束而结束,一直存在,即使应用程序关闭,也会被唤醒接受广播
(2)全局的广播
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.musicplay">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MusicService">
</service>
</application>
</manifest>
2.发送和接收(主要代码)
- 创建一个Intent
- 调用sendBroadcast()函数,把Intent携带的消息广播出去
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/previous"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_media_previous" />
<ImageButton
android:id="@+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_media_play" />
<ImageButton
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_media_pause" />
<ImageButton
android:id="@+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_media_next" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:textColor="#000000"
android:ellipsize="marquee"
android:layout_weight="1"
android:marqueeRepeatLimit="marquee_forever"/>
<TextView
android:id="@+id/author"
android:textSize="12dp"
android:gravity="center_vertical"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
MainActivity.java
public void onClick(View source) {
//创建Intent
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;
//按下上一首按钮
case R.id.previous:
intent.putExtra("control",3);
break;
//按下下一首按钮
case R.id.next:
intent.putExtra("control",4);
break;
}
//发送广播,将被Service组件中的BroadcastReceiver接收到
sendBroadcast(intent);
}
//自定义的BroadcastReceiver,负责监听从Service传回的广播
private class ActivityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//获取Intent中的update消息,update代表播放状态
int update=intent.getIntExtra("update",-1);
//获取Intent中的current消息,current代表当前正在播放的歌曲
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.mic);
//设置当前状态
status=0x12;
break;
//控制系统进入暂停状态
case 0x13:
//暂停状态下设置使用播放图标
play.setImageResource(R.drawable.play);
//设置当前状态
status=0x13;
break;
}
}
}
MusicService.java
public class MyReceiver extends BroadcastReceiver
{
@Override
public void onReceive(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;
}
break;
case 3:
//原来处于没有播放或暂停状态
if (status==0x11||status==0x13)
{
if(current==0) {
current=2;
prepareAndPlay(musics[current]);
}
//准备并播放音乐
else {
current=current-1;
prepareAndPlay(musics[current]);
}
status=0x12;
}
//原来处于播放状态
else if (status==0x12)
{
//上一首//准备并播放音乐
if(current==0) {
current=2;
prepareAndPlay(musics[current]);
}
else {
current=current-1;
prepareAndPlay(musics[current]);
}
}
break;
case 4:
//原来处于没有播放或暂停状态
if (status==0x11||status==0x13)
{
if(current==2) {
current=0;
prepareAndPlay(musics[current]);
} //准备并播放音乐
else {
current=current+1;
prepareAndPlay(musics[current]);
}
status=0x12;
}
//原来处于播放状态
else if (status==0x12)
{
//下一首
if(current==2) {
current=0;
prepareAndPlay(musics[current]);
}
else {
current=current+1;
prepareAndPlay(musics[current]);
}
}
break;
}
//广播通知Activity更改图标、文本框
Intent sendIntent=new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("update",status);
sendIntent.putExtra("current",current);
//发送广播,将被Activity组件中的BroadcastReceiver接收
sendBroadcast(sendIntent);
}
}
实现效果
源码下载
https://gitee.com/moshangxveran/MusicPlay
参考博客
https://blog.csdn.net/qq_44841678/article/details/105469490
https://www.cnblogs.com/huangxiaoying/p/6435299.html