这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战
文章目录
广播的特征
1、有一个广播的发送方,若干个接收方
2、通过“频道”匹配发送方与接收方
在 Android 系统中,把具有广播的通信方式的特征的数据传输方式称之为“广播”
BroadcastReceiver 是 Android 系统的核心组件,因此我们需要新建一个类继承 BroadcastReceiver 并注册
开发步骤
- 自定义类,继承自 BroadcastReveiver
- 在 AndroidManifest.xml 中注册该自定义的广播接收者
- 当需要发送广播时,调用
sendBroadcast(intent)方法实现发送,该方法是 Context 定义的方法,所以在 Activity 或 Service 中能直接调用该方法。在发送广播前,应该为 intent 对象配置 Action 属性,用于确定广播的“频道” - 在 AndroidManifest.xml 中找到广播接收者的注册节点,添加子级
<intent-filter>节点,配置<action/>节点属性,使之匹配广播的发送方的“频道”
栗子
目的:实现简单的发送和接受
新建 CustomReceiver 继承 BroadcastReceiver
public class CustomReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String date = intent.getStringExtra("date");
Log.d("BROADCAST","CustomReceiver->onReceive();时间:"+date);
}
}
布局文件 activity_main
<Button
android:id="@+id/btn_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送广播"/>
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btnSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSend = findViewById(R.id.btn_send);
btnSend.setOnClickListener(this);
}
@Override
public void onClick(View view) {
long date = System.currentTimeMillis();
Intent intent = new Intent();
intent.setAction("CCTV5");
intent.putExtra("date",""+date);
Log.d("BROADCAST","Mainctivity->onClick();时间:"+date);
sendBroadcast(intent);
}
}
AndroidManifest
<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">
<receiver android:name=".CustomReceiver">
<intent-filter>
<action android:name="CCTV5"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
......
</activity>
</application>
点击按钮,查看日志
D/BROADCAST: Mainctivity->onClick();时间:1523503113567
D/BROADCAST: CustomReceiver->onReceive();时间:1523503113567
由于广播可以有多个接收方,所以我们新建 CustomReceiver2
public class CustomReceiver2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String date = intent.getStringExtra("date");
Log.d("BROADCAST","CustomReceiver2->onReceive();时间:"+date);
}
}
AndroidManifest中注册
<receiver android:name=".CustomReceiver2">
<intent-filter>
<action android:name="CCTV5"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
点击按钮查看日志
D/BROADCAST: Mainctivity->onClick();时间:1523503682968
D/BROADCAST: CustomReceiver->onReceive();时间:1523503682968
D/BROADCAST: CustomReceiver2->onReceive();时间:1523503682968
报错处理:Background execution not allowed
Android 8以上并不会正常接收到广播,而是会输出警告:Background execution not allowed
解决办法1:因为这是静态广播注册才会有的问题,所以可以考虑将静态广播修改为动态广播。
解决办法2:增加 packageName
Intent intent = new Intent();
intent.setPackage("com.example.testapplication");
intent.setAction("CCTV5");
intent.putExtra("date", "" + date);
Log.d("BROADCAST", "Mainctivity->onClick();时间:" + date);
sendBroadcast(intent);
广播的注册类型
- 静态注册:在项目清单中注册,这种方式注册的广播接收者是常驻型的,即只要 APP 安装到手机上就会接收广播,直至 APP 被卸载,而无视该 APP 有没有在手机上运行
- 动态注册:在程序运行过程中注册,
registerReceiver(receiver,filter)方法注册,这种方式注册的广播接收者,仅当注册后才开始接收广播,需要停止接受时,应该调用unregisterReceiver(receiver);注销
栗子
在页面增加两个按钮
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btnSend;
private Button btnResiger;
private Button btnUnregister;
private InnerReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSend = findViewById(R.id.btn_send);
btnResiger = findViewById(R.id.btn_register_receiver);
btnUnregister = findViewById(R.id.btn_unregister_receiver);
btnSend.setOnClickListener(this);
btnResiger.setOnClickListener(this);
btnUnregister.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_send:
long date = System.currentTimeMillis();
Intent intent = new Intent();
intent.setPackage("com.example.testapplication");
intent.setAction("CCTV5");
intent.putExtra("date", "" + date);
Log.d("BROADCAST", "Mainctivity->onClick();时间:" + date);
sendBroadcast(intent);
break;
case R.id.btn_register_receiver:
if (receiver == null) {
receiver = new InnerReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("CCTV5");
registerReceiver(receiver, filter);
}
break;
case R.id.btn_unregister_receiver:
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
break;
}
}
private class InnerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String date = intent.getStringExtra("date");
Log.d("BROADCAST", "InnerReceiver->onReceive();时间:" + date);
}
}
}
先点击发送广播
D/BROADCAST: Mainctivity->onClick();时间:1523505690920
D/BROADCAST: CustomReceiver->onReceive();时间:1523505690920
D/BROADCAST: CustomReceiver2->onReceive();时间:1523505690920
点击注册内部接收者,再点击发送广播
D/BROADCAST: Mainctivity->onClick();时间:1523505725969
D/BROADCAST: InnerReceiver->onReceive();时间:1523505725969
D/BROADCAST: CustomReceiver->onReceive();时间:1523505725969
D/BROADCAST: CustomReceiver2->onReceive();时间:1523505725969
点击注销内部接收者,再点击发送广播
D/BROADCAST: Mainctivity->onClick();时间:1523505817228
D/BROADCAST: CustomReceiver->onReceive();时间:1523505817228
D/BROADCAST: CustomReceiver2->onReceive();时间:1523505817228