BroadcastReceiver是用来接收广播通知的组件,广播是一种同时通知多个对象的事件通知机制。类似于日常生活中的广播,允许多人同时接收,也允许不收听。Android中的广播来源与系统事件,例如按下拍照按键,电池电量低,安装新应用,启动特定线程,文件下载完毕等。
BroadcastReceiver类是所有广播接收器的抽象基类,其实现类用来对发出来的广播进行筛选并做出响应。广播接收器的生命周期非常的简单,当消息到达时,接收器调用 onReceiver()方法,在该方法接收之后,BroadcastReceiver实例失效。
广播接收器通常初始化独立的组件或者在onReceiver()方法中发送通知给用户。如果广播接收器须要完成更加耗时的操作,它应该启动服务而不是一个线程,因为不活跃的广播接收器可能被系统停止。
用于接收的广播有两大类:即普通广播和有序广播
普通广播:使用Context.sendBroadcast()方法发送, 他们是完全异步的,广播的全部接收者以未定义的顺序运行,通常在同一时间,这种方法非常高效,但是接收者不能使用结果或者终止API。
有序广播:使用Context.sendOrderedBroadcast()方法发送,他们每次只发送给一个接收者,由于每个接收者依次运行,它能为下一个接收者生成一个结果,或者它能完全终止广播以便不传递给其他接收者,有序接收者运行顺序由匹配的intent-filter的android:priority属性控制,具有相同优先级的接收者运行顺序随机。
<receiver android:name="myRecevice"> //继承BroadcastReceiver,重写onReceiver方法
<intent-filter>
<action android:name="com.xxxx.xxx"/>//使用过滤器,接收指定action广播
intent-filter>
receiver>
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(String); //为BroadcastReceiver指定action,使之用于接收同action的广播
registerReceiver(BroadcastReceiver,intentFilter);
通过这种方式注册的广播为非常驻型广播,即它会跟随Activity的生命周期,所以在Activity结束前我们需要调用unregisterReceiver(receiver)方法移除它。
指定广播目标Action:Intent intent = new Intent(actionString);
并且可通过Intent携带消息 :intent.putExtra(“msg”, “hi,我通过广播发送消息了”);
发送广播消息:Context.sendBroadcast(intent )
例如我们通过一个按钮的点击事件来获取 现在的电池电量:
我们在Activity中放一个按钮,在按钮的点击事件下注册并发送广播,在接收器中Toast出当前的电量:
点击事件下添加代码:
registerReceiver(new TestReceiver(),new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
广播接收器为:
public class TestReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) ;//电量
int level = intent.getIntExtra("level", 0);
int scale = intent.getIntExtra("scale", 100);
Toast.makeText(context, "剩余电量为:" + (level * 100 / scale) + "%", Toast.LENGTH_SHORT).show();
}
}
这里须要注意的是,我们获取电量只能带代码中动态注册,如果是在 AndroidManifest.xml里面 静态注册 ,设置过滤器 为 android.intent.action.BATTERY_CHANGED 就不能成功,因为Android机制的原因,受保护的广播是只有系统才能发送的。哪些才是受保护的广播呢,传送门:http://www.cnblogs.com/xueqiang911226/p/3891852.html
首先我们先实现一个我们自己的广播接收者:
public class TestReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("android.intent.action.MY_BROADCAST")) ;
Toast.makeText(context, intent.getStringExtra("msg"), Toast.LENGTH_SHORT).show();
}
}
然后我们在配置文件中注册我们的广播:
<receiver android:name=".TestReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_BROADCAST"/>
<category android:name="android.intent.category.DEFAULT"/>
intent-filter>
receiver>
然后我们在一个按钮的点击事件下发送一条广播,在上述的TestBraodcast的onReceiver()方法中匹配action并且读取我们传递的msg数据:
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("android.intent.action.MY_BROADCAST");
intent.putExtra("msg", "这是一条测试广播");
sendBroadcast(intent);
}
});
监听网络状态的一个广播实例:http://blog.csdn.net/centralperk/article/details/7597516
我们的Activity的布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册广播" />
<Button
android:id="@+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送广播" />
LinearLayout>
我们的Activity 的代码为:
public class MainActivity extends PermissionActivity {
private Button btn1, btn2;
TestReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
btn1 = (Button) findViewById(R.id.btn_1);
btn2 = (Button) findViewById(R.id.btn_2);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//动态注册我们的广播
receiver = new TestReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.MY_BROADCAST");
registerReceiver(receiver, filter);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//发送一条带msg的广播
Intent intent = new Intent("android.intent.action.MY_BROADCAST");
intent.putExtra("msg", "我是动态注册的信息");
sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
//销毁页面时候移除注册的广播。
unregisterReceiver(receiver);
}
}
广播接收器的代码为:
public class TestReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//为什么要验证,因为 我们可以在这个接收器里面接收好几种不同类型的广播
//当然你也可以根据自己intent传递一个专门的标志参数来区分。
if (action.equals("android.intent.action.MY_BROADCAST")) ;
Toast.makeText(context, intent.getStringExtra("msg"), Toast.LENGTH_SHORT).show();
}
}
我们在Activity中分别注册三个不同优先级的广播。然后创建三个对应的广播接收器,然后打印Log看看顺序:
Activity代码:
public class MainActivity extends PermissionActivity {
private Button btn1, btn2;
TestReceiver receiver = new TestReceiver();
TestReceiver1 receiver1 = new TestReceiver1();
TestReceiver2 receiver2 = new TestReceiver2();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
btn1 = (Button) findViewById(R.id.btn_1);
btn2 = (Button) findViewById(R.id.btn_2);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//动态注册我们的广播
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.MY_BROADCAST");
filter.setPriority(999);
registerReceiver(receiver, filter);
IntentFilter filter1 = new IntentFilter();
filter1.addAction("android.intent.action.MY_BROADCAST");
filter1.setPriority(998);
registerReceiver(receiver1, filter1);
IntentFilter filter2 = new IntentFilter();
filter2.addAction("android.intent.action.MY_BROADCAST");
filter2.setPriority(997);
registerReceiver(receiver2, filter2);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//发送一条带msg的广播
Intent intent = new Intent("android.intent.action.MY_BROADCAST");
intent.putExtra("msg", "我是动态注册的信息");
// sendBroadcast(intent);
MainActivity.this.sendOrderedBroadcast(intent,null);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
//销毁页面时候移除注册的广播。
unregisterReceiver(receiver);
unregisterReceiver(receiver1);
unregisterReceiver(receiver2);
}
}
Activity 的xml代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册广播" />
<Button
android:id="@+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送广播" />
LinearLayout>
三个广播接收器的代码为:
public class TestReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//为什么要验证,因为 我们可以在这个接收器里面接收好几种不同类型的广播
//当然你也可以根据自己intent传递一个专门的标志参数来区分。
if (action.equals("android.intent.action.MY_BROADCAST")) ;
//创建一个Bundle对象,并存入数据
Bundle bundle = new Bundle();
bundle.putString("msg", intent.getStringExtra("msg"));
//将bundle放入结果中
setResultExtras(bundle);
//取消Broadcast的继续发送
Log.i("receiver0",intent.getStringExtra("msg"));
}
}
public class TestReceiver1 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//为什么要验证,因为 我们可以在这个接收器里面接收好几种不同类型的广播
//当然你也可以根据自己intent传递一个专门的标志参数来区分。
if (action.equals("android.intent.action.MY_BROADCAST")) ;
Bundle bundle = getResultExtras(true);
//解析前一个BroadcastReceiver所存入的key为first的消息
String first = bundle.getString("msg");
Log.i("receiver1", first);
//可以更新新的数据往下传递
// Bundle bundle1 = new Bundle();
// bundle1.putString("msg", first);
// //将bundle放入结果中
// setResultExtras(bundle1);
}
}
public class TestReceiver2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//为什么要验证,因为 我们可以在这个接收器里面接收好几种不同类型的广播
//当然你也可以根据自己intent传递一个专门的标志参数来区分。
if (action.equals("android.intent.action.MY_BROADCAST")) ;
Bundle bundle = getResultExtras(true);//是否接收上一个广播的数据
String str= bundle.getString("msg");
Log.i("receiver2",str);
abortBroadcast();//停止继续往下发送
}
}
当然我们如果只是按顺序接收相同的信息。那么我们在每个接收器里面直接打印 Log.i(“receiver0/1/2”,intent.getStringExtra(“msg”)); 就可以看出来其是按照顺序发送了,然后我们在Activity中注释掉 filter.setPriority(999);的那几句,或者将里面的数值改为相同,那么就可以验证是否是无序的。【当然我们须要注释掉abortBroadcast()方法,否则会报BroadcastReceiver trying to return result during a non-ordered broadcast异常】