BoradcastReceiver是Android下的四大组件之一,用于接收其他Service或者Activity发送的广播。
首先,要接受广播,得有一个广播的发送源。这个发送源,可以是其他应用的Activity、Service,也可以是当前应用的Activity或者Service。发送广播的方法非常简单:
Intent intent=new Intent();
//设置intent
intent.setAction(target);
//发送广播
sendBroadcast(intent);
主要是创建一个Intent对象,并设置其各个方面的参数(如Action,Type和Data),然后调用sendBroadcast方法即可发送广播。下面是一个实例:
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.amia.broadcasttest.SendActivity">
<Button
android:id="@+id/send_button"
android:text="发送广播"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
在Activity中设置按钮的点击事件:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendBroad();
}
});
sendBorad方法:
private void sendBroad(){
Intent intent=new Intent();
//设置intent
intent.setAction(target);
//发送广播
sendBroadcast(intent);
}
此时我们点击按钮,什么事都不会发生,原因是只有广播的发送者而没有接受者。为了让该信息被接收并利用,我们必须设置指定的广播接收者。我们需要创建一个类继承BroadcastReceiver并实现onReceive()方法。需要注意的是,如果你把这个类作为某个Activity的内部类并且希望能够在Activity没有被创建的时候能接受到消息,则需要注意在AndroidManifest.xml中配置Receiver,如下:
<receiver android:name=".RecActivity$MyBroadcast"
>
<intent-filter>
<action android:name="com.example.amia.broadcasttest.test1"/>
</intent-filter>
</receiver>
并且需要将BroadcastReceiver设置为public和static。
android:name是该类的名字;Intent-filter中的参数用于过滤希望能被该广播接收者接收到的广播。
继承BroadcastReceiver的类,在这里作为RecActivity的内部类来使用:
public static class MyBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"收到广播",Toast.LENGTH_SHORT).show();
Log.i("RecActivity","收到广播");
}
}
运行后点击按钮可以看见MyBroadcast已经接收到到广播。
将BroadcastReceiver作为外部类也是一样的用法,此处不再啰嗦。
如果需要将BroadcastReceiver设置为Activity启动的时候才有效,则无需在AndroidManifest.xml中配置,只需要在Activity中注册BroadcastReceiver就可以了。
新建一个Activity命名为RecActivity并注册监听者:
BroadcastReceiver broadcast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rec);
broadcast=new MyBroadcast();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(SendActivity.target);
registerReceiver(broadcast,intentFilter);
}
注意取消注册:
protected void onDestroy(){
unregisterReceiver(broadcast);//注销广播接受者
super.onDestroy();
}
BroadcastReceiver的实现不需要声明为public 和static:
class MyBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"收到广播",Toast.LENGTH_SHORT).show();
Log.i("RecActivity","收到广播");
}
}
这时候点击按钮是没有任何反应的,因为没有任何接收者(Atctivity并未启动,所以未注册广播接受者),我们只需要先让接受的Activity启动再发送广播即可,在SendActivity中修改发送的方法:
private void sendBorad(){
Intent intent1=new Intent(this,com.example.amia.broadcasttest.RecActivity.class);
startActivity(intent1);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent intent=new Intent();
//设置intent
intent.setAction(target);
//发送广播
sendBroadcast(intent);
}
}).start();
}
这时候点击按钮之后Activity被创建,并接收到消息:
至于为什么要在线程中发送广播,是因为如果立刻发送广播,创建新的Activity并注册接受者之前,广播可能先被发送,这样后面创建的接受者就无法接收到广播了。在实际开发中基本上应该不会这么写,这里只是实现一下示例而已。