BroadcastReceiver是用来接收广播通知的组件,广播是一种同时通知多个对象的事件通知机制。类似于日常生活中的广播,允许多人同时接收,也允许不收听。Android中的广播来源与系统事件,例如按下拍照按键,电池电量低,安装新应用,启动特定线程,文件下载完毕等。

BroadcastReceiver类是所有广播接收器的抽象基类,其实现类用来对发出来的广播进行筛选并做出响应。广播接收器的生命周期非常的简单,当消息到达时,接收器调用 onReceiver()方法,在该方法接收之后,BroadcastReceiver实例失效。

广播接收器通常初始化独立的组件或者在onReceiver()方法中发送通知给用户。如果广播接收器须要完成更加耗时的操作,它应该启动服务而不是一个线程,因为不活跃的广播接收器可能被系统停止。

接收广播的两种分类

用于接收的广播有两大类:即普通广播和有序广播

普通广播:使用Context.sendBroadcast()方法发送, 他们是完全异步的,广播的全部接收者以未定义的顺序运行,通常在同一时间,这种方法非常高效,但是接收者不能使用结果或者终止API。

有序广播:使用Context.sendOrderedBroadcast()方法发送,他们每次只发送给一个接收者,由于每个接收者依次运行,它能为下一个接收者生成一个结果,或者它能完全终止广播以便不传递给其他接收者,有序接收者运行顺序由匹配的intent-filter的android:priority属性控制,具有相同优先级的接收者运行顺序随机。

广播的两种注册机制

静态注册:在AndroidManifest.xml中用标签生命注册,并在标签内用标签设置过滤器。

  <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的布局:

<?xml version="1.0" encoding="utf-8"?><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代码:

<?xml version="1.0" encoding="utf-8"?><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异常】

更多相关文章

  1. Android操作JNI函数以及复杂对象传递
  2. Activity 生命周期(一)
  3. Android(安卓)组件系列-----Activity保存状态
  4. Android(安卓)带清除功能的输入框控件ClearEditText
  5. android: 接收和发送短信
  6. Android自学笔记-14-意图(Intent)
  7. Android(安卓)程序在系统中如何完成启动
  8. Activity从屏幕底部滑出、滑入、处理黑色背景和状态栏
  9. Android之AsyncTask的用法

随机推荐

  1. Grnymotion模拟器和Android真机访问PC端T
  2. android 之 长度单位
  3. android图像处理系列之七--图片涂鸦,水印-图
  4. Android(安卓)Layout 之 RelativeLayout
  5. ADB基本命令
  6. 百度地图 Android(安卓)SDK - 新的版本号
  7. Android(安卓)SDK更新困难解决方法
  8. android adb常用命令集
  9. Android之AIDL使用解析
  10. Android(安卓)启动页白屏 快速解决