您的位置:首页 > 移动开发 > Android开发

Android BroadcastReceiver使用详解

2017-02-06 11:46 323 查看
想要全面了解广播,须知以下几点

1、创建广播接收者类
    继承BroadcastReceiver,重写onReceive方法, 以MyReceiver extends BroadcastReceiver为例子
    public void onReceive(Context context, Intent intent){}
---------------------------------------------------------------------------------------------

2、静态注册广播or动态注册广播
---------------------------------------------------------------------------------------------
    2.1 静态注册广播
          

静态注册

静态注册是在AndroidManifest.xml文件中配置的,我们就来为MyReceiver注册一个广播地址:

[html] view
plain copy

<receiver android:name=".MyReceiver">  

            <intent-filter>  

                <action android:name="android.intent.action.MY_BROADCAST"/>  

                <category android:name="android.intent.category.DEFAULT" />  

            </intent-filter>  

        </receiver>  

配置了以上信息之后,只要是android.intent.action.MY_BROADCAST这个地址的广播,MyReceiver都能够接收的到。注意,这种方式的注册是常驻型的,也就是说当应用关闭后,如果有广播信息传来,MyReceiver也会被系统调用而自动运行。

     2.2 动态注册广播

动态注册

动态注册需要在代码中动态的指定广播地址并注册,通常我们是在Activity或Service注册一个广播,下面我们就来看一下注册的代码:

[java] view
plain copy

MyReceiver receiver = new MyReceiver();  

          

IntentFilter filter = new IntentFilter();  

filter.addAction("android.intent.action.MY_BROADCAST");  

          

registerReceiver(receiver, filter);  

注意,registerReceiver是android.content.ContextWrapper类中的方法,Activity和Service都继承了ContextWrapper,所以可以直接调用。在实际应用中,我们在Activity或Service中注册了一个BroadcastReceiver,当这个Activity或Service被销毁时如果没有解除注册,系统会报一个异常,提示我们是否忘记解除注册了。所以,记得在特定的地方执行解除注册操作:

[java] view
plain copy

@Override  

protected void onDestroy() {  

    super.onDestroy();  

    unregisterReceiver(receiver);  

}  

执行这样行代码就可以解决问题了。注意,这种注册方式与静态注册相反,不是常驻型的,也就是说广播会跟随程序的生命周期。
------------------------------------------------------------------------------

3、我们可以根据以上任意一种方法完成注册,当注册完成之后,这个接收者就可以正常工作了。我们可以用以下方式向其发送一条广播:

[java] view
plain copy

public void send(View view) {  

    Intent intent = new Intent("android.intent.action.MY_BROADCAST");  

    intent.putExtra("msg", "hello receiver.");  

    sendBroadcast(intent);  

}  

注意,sendBroadcast也是android.content.ContextWrapper类中的方法,它可以将一个指定地址和参数信息的Intent对象以广播的形式发送出去。

----------------------------------------------------------------------------

4、普通广播和有序广播
4.1 Normal Broadcast(普通广播):Normal Broadcast是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高。但缺点是接受者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent的广播。

 4.2 Ordered Broadcast(有序广播):Ordered Broadcast的接收者将按预先声明的优先级依次接受Broadcast。如:A的级别高于B、B的级别高于C,那么Broadcast先传给A,再传给B,最后传给C。优先级别声明在<intent-filter.../>元素的android:priority属性中,数越大优先级别越高,取值范围为-1000-1000,优先级别也可以调用IntentFilter对象的setPriority()进行设置。OrderedBroadcast接收者可以终止Broadcast
Intent的传播,BroadcastIntent的传播一旦终止,后面的接收者就无法接收到Broadcast。另外,OrderedBroadcast的接收者可以将数据传递给下一个接收者。如:A得到Broadcast后,可以往它的结果对象中存入数据,当Broadcast传给B时,B可以从A的结果对象中得到A存入的数据。
4.3 context提供的如下两个方法用于发送广播:
      sendBroadcast():发送Normal Broadcast
      sendOrderedBroadcast():发送OrderedBroadcast。

4.4 对于OrderedBroadcast而言,系统会根据接收者生命的优先级别顺序逐个执行接收者,优先接收到Broadcast的接收者可以终止Broadcast,调用BroadcastReceiver的abortBroadcast()方法即可终止Broadcast。如果Broadcast被前面的接收者终止,后面的接收者就再也无法获取到Broadcast。

4.5 不仅如此,对于OrderBroadcast而言,优先接收到Broadcast的接收者可以通过setResultExtras(Bundle)方法将处理结果存入Broadcast中,然后传给下一个接收者,下一个接收者通过代码: Bundle bundle=getResultExtras(true)可以获取上一个接收者存入的数据。

有序广播示例

如下:

[java] view
plain copy

package com.scott.receiver;  

  

import android.content.BroadcastReceiver;  

import android.content.Context;  

import android.content.Intent;  

import android.os.Bundle;  

import android.util.Log;  

  

public class FirstReceiver extends BroadcastReceiver {  

      

    private static final String TAG = "OrderedBroadcast";  

      

    @Override  

    public void onReceive(Context context, Intent intent) {  

        String msg = intent.getStringExtra("msg");  

        Log.i(TAG, "FirstReceiver: " + msg);  

          

        Bundle bundle = new Bundle();  

        bundle.putString("msg", msg + "@FirstReceiver");  

        setResultExtras(bundle);  

    }  

  

}  

[java] view
plain copy

public class SecondReceiver extends BroadcastReceiver {  

      

    private static final String TAG = "OrderedBroadcast";  

      

    @Override  

    public void onReceive(Context context, Intent intent) {  

        String msg = getResultExtras(true).getString("msg");  

        Log.i(TAG, "SecondReceiver: " + msg);  

          

        Bundle bundle = new Bundle();  

        bundle.putString("msg", msg + "@SecondReceiver");  

        setResultExtras(bundle);  

    }  

  

}  

[java] view
plain copy

public class ThirdReceiver extends BroadcastReceiver {  

      

    private static final String TAG = "OrderedBroadcast";  

      

    @Override  

    public void onReceive(Context context, Intent intent) {  

        String msg = getResultExtras(true).getString("msg");  

        Log.i(TAG, "ThirdReceiver: " + msg);  

    }  

  

}  

我们注意到,在FirstReceiver和SecondReceiver中最后都使用了setResultExtras方法将一个Bundle对象设置为结果集对象,传递到下一个接收者那里,这样以来,优先级低的接收者可以用getResultExtras获取到最新的经过处理的信息集合。

代码改完之后,我们需要为三个接收者注册广播地址,我们修改一下AndroidMainfest.xml文件:

[html] view
plain copy

<receiver android:name=".FirstReceiver">  

    <intent-filter android:priority="1000">  

        <action android:name="android.intent.action.MY_BROADCAST"/>  

        <category android:name="android.intent.category.DEFAULT" />  

    </intent-filter>  

</receiver>  

<receiver android:name=".SecondReceiver">  

    <intent-filter android:priority="999">  

        <action android:name="android.intent.action.MY_BROADCAST"/>  

        <category android:name="android.intent.category.DEFAULT" />  

    </intent-filter>  

</receiver>  

<receiver android:name=".ThirdReceiver">  

    <intent-filter android:priority="998">  

        <action android:name="android.intent.action.MY_BROADCAST"/>  

        <category android:name="android.intent.category.DEFAULT" />  

    </intent-filter>  

</receiver>  

我们看到,现在这三个接收者的<intent-filter>多了一个android:priority属性,并且依次减小。这个属性的范围在-1000到1000,数值越大,优先级越高。

现在,我们需要修改一下发送广播的代码,如下:

[java] view
plain copy

public void send(View view) {  

    Intent intent = new Intent("android.intent.action.MY_BROADCAST");  

    intent.putExtra("msg", "hello receiver.");  

    sendOrderedBroadcast(intent, "scott.permission.MY_BROADCAST_PERMISSION");  

}  

注意,使用sendOrderedBroadcast方法发送有序广播时,需要一个权限参数,如果为null则表示不要求接收者声明指定的权限,如果不为null,则表示接收者若要接收此广播,需声明指定权限。这样做是从安全角度考虑的,例如系统的短信就是有序广播的形式,一个应用可能是具有拦截垃圾短信的功能,当短信到来时它可以先接受到短信广播,必要时终止广播传递,这样的软件就必须声明接收短信的权限。

所以我们在AndroidMainfest.xml中定义一个权限:

[html] view
plain copy

<permission android:protectionLevel="normal"  

            android:name="scott.permission.MY_BROADCAST_PERMISSION" />  

然后声明使用了此权限:

[html] view
plain copy

<uses-permission android:name="scott.permission.MY_BROADCAST_PERMISSION" />  

关于这部分如果有不明白的地方可以参考Scott Liu之前写过的一篇文章:Android声明和使用权限

参考博文:http://blog.csdn.net/liuhe688/article/details/6955668
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  broadcastreceiver