在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的 Broadcast进行过滤接受并响应的一类组件。由于BroadcastReceiver本质上也是一种监听器,一次实现BroadcastReceiver只要重写其onReceive(Context context, Intent intent) 方法就可以了。
实现方法:
1.注册BroadcastReceiver
2.发送Broadcast消息
3.重写onReceive()方法
注册BroadcastReceiver有两种方式:静态注册方式和动态注册方式。下面依次介绍
静态注册方法:
是在在AndroidManifest.xml中用标签生命注册,并在标签内用标签设置过滤器
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="9">
<action android:name="org.crazyit.learnbroadcastreceive.intent.action.MyReceiver" />
</intent-filter>
</receiver>
会在Android Studio自动完成。
动态注册方法:
//为了防止重复注册多个BroadcastReceivr
if(receiver==null){
receiver=new MyReceiver();
registerReceiver(receiver,new IntentFilter(MyReceiver.ACTION));
}
卸载:
if(receiver!=null){
unregisterReceiver(receiver);
receiver=null;
}
2.发送Broadcast消息
Intent intent=new Intent(MyReceiver.ACTION);
//通过Intent携带一些数据
intent.putExtra("data","jikexueyuan");
//sendBroadcast(intent);
//发送有序消息,可以被优先级高的
//BroadcastReceiver接收到消息后阻断,
//此时优先级低的BroadcastReceiver不能继续受到消息
sendOrderedBroadcast(intent,null);
3.重写onReceive()方法
我们可以设置接收器不同的优先级,当发送无序消息时,逻辑上所有接收器是同时接收到消息的,缺点是接受者不能将处理过的消息发送给下一个接受者。而有序消息是按预先声明的优先级一次接收的。如果优先级A>B,则先A接收到消息,A再把消息(可以处理)传给B,也可以A直接把消息阻断,不允许B接收。
接收器MyReceiver接收消息,并阻断:
public void onReceive(Context context, Intent intent) {
System.out.println("接收到了消息,消息的内容是:"+intent.getStringExtra("data"));
//用来中断优先级排在他后面的接收器接收到消息,不过前提是发送的消息是有序的,即sendOrderedBroadcast;
abortBroadcast();
}
此时优先级较低的MyReceiver1将不能接收到任何消息
接收器MyReceiver接收消息,并把消息处理后传递给MyReceiver1
public void onReceive(Context context, Intent intent) {
System.out.println("接收到了消息,消息的内容是:"+intent.getStringExtra("data"));
//用来中断优先级排在他后面的接收器接收到消息,不过前提是发送的消息是有序的,即sendOrderedBroadcast;
//abortBroadcast();
Bundle bundle=new Bundle();
bundle.putString("first","我是MyReceiver传送的消息");
//将 bundle放入结果中
setResultExtras(bundle);
}
此时MyReceiver1将接收到消息:
public void onReceive(Context context, Intent intent) {
System.out.println("MyReceive1接收到了消息");
Bundle b=getResultExtras(true);
//解析第一个BroadcastReceiver传递过来key为first的消息
String string=b.getString("first");
Toast.makeText(context,"第二个receiver接收到的消息是:第一个receiver传过来的消息"+
string+"和MainActivity传给第一个Receiver的消息:"+intent.getStringExtra("data"),Toast.LENGTH_SHORT).show();
}
最后附上总的代码:
MainActivity.java
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button btnSendMsg;
Button btnReg,btnUnreg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSendMsg=(Button) findViewById(R.id.btnSendMsg);
btnReg=(Button) findViewById(R.id.btnReg);
btnUnreg=(Button) findViewById(R.id.btnUnreg);
btnSendMsg.setOnClickListener(this);
btnReg.setOnClickListener(this);
btnUnreg.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btnSendMsg:
/* 通过Manifest文件进行注册时
Intent intent=new Intent(this,MyReceiver.class);
//通过Intent携带一些数据
intent.putExtra("data","jikexueyuan");
sendBroadcast(intent);*/
/*
* 通过下面java代码进行注册时*/
Intent intent=new Intent(MyReceiver.ACTION);
//通过Intent携带一些数据
intent.putExtra("data","jikexueyuan");
//sendBroadcast(intent);
//发送有序消息,可以被优先级高的BroadcastReceiver接收到消息后阻断,
// 优先级低的BroadcastReceiver不能继续受到消息
sendOrderedBroadcast(intent,null);
break;
//在java代码中注册和注销接收器更加的灵活啊,可以用在不需要时刻接收消息的情况下
case R.id.btnReg:
//为了防止重复注册多个BroadcastReceivr
if(receiver==null){
receiver=new MyReceiver();
registerReceiver(receiver,new IntentFilter(MyReceiver.ACTION));
}
break;
case R.id.btnUnreg:
if(receiver!=null){
unregisterReceiver(receiver);
receiver=null;
}
break;
}
}
private MyReceiver receiver=null;
}
MyReceiver.java
//程序发送有序Broadcast,MainActivity传送消息A给 MyReceiver, MyReceiver继续传送消息B给MyReceiver1
//此消息B可以是消息A,也可以不是
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class MyReceiver extends BroadcastReceiver {
public static final String ACTION="org.crazyit.learnbroadcastreceive.intent.action.MyReceiver";
public MyReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("接收到了消息,消息的内容是:"+intent.getStringExtra("data"));
//用来中断优先级排在他后面的接收器接收到消息,不过前提是发送的消息是有序的,即sendOrderedBroadcast;
//abortBroadcast();
Bundle bundle=new Bundle();
bundle.putString("first","我是MyReceiver传送的消息");
//将 bundle放入结果中
setResultExtras(bundle);
}
}
MyReceiver1.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
public class MyReceiver1 extends BroadcastReceiver {
public MyReceiver1() {
}
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("MyReceive1接收到了消息");
Bundle b=getResultExtras(true);
//解析第一个BroadcastReceiver传递过来key为first的消息
String string=b.getString("first");
Toast.makeText(context,"第二个receiver接收到的消息是:第一个receiver传过来的消息"+
string+"和MainActivity传给第一个Receiver的消息:"+intent.getStringExtra("data"),Toast.LENGTH_SHORT).show();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.crazyit.learnbroadcastreceive">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
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>
<!-- 这段代码也可以注释掉,然后在java程序里面实现动态注册与注销BroadcastReceive -->
<!-- <receiver -->
<!-- android:name=".MyReceiver" -->
<!-- android:enabled="true" -->
<!-- android:exported="true"></receiver> -->
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="9">
<action android:name="org.crazyit.learnbroadcastreceive.intent.action.MyReceiver" />
</intent-filter>
</receiver>
<receiver
android:name=".MyReceiver1"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="8">
<action android:name="org.crazyit.learnbroadcastreceive.intent.action.MyReceiver" />
</intent-filter>
</receiver>
</application>
</manifest>
BroadcasrReceiver还可以接收系统广播,例如
<receiver android:name=".BootBroadcasrReceiver" >
<intent-filter>
<!-- 接受系统开机广播 -->
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.HOME"/>
</intent-filter>
</receiver>
然后只要在onReceiver函数中启动某个Service,此Service就是开机启动的。