分享

Android BroadcastReceiver 简介 - 蔚蓝天空 探索无限 - Ja...

 liluvu 2010-12-07
Android BroadcastReceiver 简介
在 Android 中使用 Activity, Service, Broadcast, BroadcastReceiver
   活动(Activity) - 用于表现功能 
   服务(Service) - 相当于后台运行的 Activity
   广播(Broadcast) - 用于发送广播 
   广播接收器(BroadcastReceiver) - 用于接收广播
   Intent - 用于连接以上各个组件,并在其间传递消息

BroadcastReceiver
    在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的 Broadcast进行过滤接受并响应的一类组件。下面将详细的阐述如何发送Broadcast和使用BroadcastReceiver过

滤接收的过程:
    首先在需要发送信息的地方,把要发送的信息和用于过滤的信息(如Action、Category)装入一个Intent对象,然后通过调用 Context.sendBroadcast()、sendOrderBroadcast()或sendStickyBroadcast()方法,把 Intent对象以广播方式发送出去。
    当Intent发送以后,所有已经注册的BroadcastReceiver会检查注册时的IntentFilter是否与发送的Intent相匹配,若 匹配则就会调用BroadcastReceiver的onReceive()方法。所以当我们定义一个BroadcastReceiver的时候,都需要 实现onReceive()方法。



注册BroadcastReceiver有两种方式:
    一种方式是,静态的在AndroidManifest.xml中用<receiver>标签生命注册,并在标签内用<intent- filter>标签设置过滤器。

    另一种方式是,动态的在代码中先定义并设置好一个 IntentFilter对象,然后在需要注册的地方调 Context.registerReceiver()方法,如果取消时就调用Context.unregisterReceiver()方法。如果用动 态方式注册的BroadcastReceiver的Context对象被销毁时,BroadcastReceiver也就自动取消注册了。

    另外,若在使用sendBroadcast()的方法是指定了接收权限,则只有在AndroidManifest.xml中用<uses- permission>标签声明了拥有此权限的BroascastReceiver才会有可能接收到发送来的Broadcast。

    同样,若在注册BroadcastReceiver时指定了可接收的Broadcast的权限,则只有在包内的AndroidManifest.xml中 用<uses-permission>标签声明了,拥有此权限的Context对象所发送的Broadcast才能被这个 BroadcastReceiver所接收。

动态注册:
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(String);--为 BroadcastReceiver指定action,使之用于接收同action的广播 registerReceiver(BroadcastReceiver,intentFilter);
    一般:在onStart中注册,onStop中取消unregisterReceiver

发送广播消息:extends Service
    指定广播目标Action:Intent Intent = new Intent(action-String)
    --指定了此action的receiver会接收此广播
    需传递参数(可选) putExtra();
    发送:sendBroadcast(Intent);
 
 
前面分别讨论了Activity和Service,这次就轮到BroastcastReceiver,Broastcast是应用程序间通信的手段。BroastcastReceiver也是跟Intent紧密相连的,动态/静态注册了BroastcastReceiver之后,使用sendBroadcast把Intent发送之后,系统会自动把符合条件的BroastcastReceiver启动,跟嵌入式系统的中断类似。
        本文主要演示了如何静态/动态注册BroastcastReceiver,向系统索取电量信息,以及枚举信息的字段。本文运行截图如下:
 
 

上图是发送Intent至内部动态注册的BroadcastReceiver,接收到之后显示消息名称。动态注册BroadcastReceiver用到registerReceiver()。
 
 
上图是发送Intent至内部静态注册的BroadcastReceiver,接收到之后显示消息名称。静态注册比动态注册麻烦点,先新建一个类继承BroadcastReceiver,然后到AndroidManifest.xml 添加
view plaincopy to clipboardprint?
01.<receiver android:name="clsReceiver2"> 
02.    <intent-filter> 
03.        <action 
04.            android:name="com.testBroadcastReceiver.Internal_2"/> 
05.    </intent-filter> 
06.</receiver> 
  <receiver android:name="clsReceiver2">
   <intent-filter>
    <action
     android:name="com.testBroadcastReceiver.Internal_2"/>
   </intent-filter>
  </receiver>
第一个name是类名,第二个是action的名称。
 
上图是枚举Intent消息的字段,这个功能比较适合懒人,把收到的Intent消息的字段全部分解了,再看看哪个需要的,懒得记住。实现这部分的代码如下:

view plaincopy to clipboardprint?
01.//当未知Intent包含的内容,则需要通过以下方法来列举  
02.                Bundle b=intent.getExtras();  
03.                Object[] lstName=b.keySet().toArray();  
04. 
05.                for(int i=0;i<lstName.length;i++)  
06.                {  
07.                    String keyName=lstName[i].toString();  
08.                    Log.e(keyName,String.valueOf(b.get(keyName)));  
09.                } 
//当未知Intent包含的内容,则需要通过以下方法来列举
    Bundle b=intent.getExtras();
    Object[] lstName=b.keySet().toArray();
    for(int i=0;i<lstName.length;i++)
    {
     String keyName=lstName[i].toString();
     Log.e(keyName,String.valueOf(b.get(keyName)));
    }
main.xml的代码如下:
view plaincopy to clipboardprint?
01.<?xml version="1.0" encoding="utf-8"?> 
02.<LinearLayout xmlns:android="http://schemas./apk/res/android
03.    android:orientation="vertical" android:layout_width="fill_parent" 
04.    android:layout_height="fill_parent"> 
05. 
06.    <Button android:id="@+id/Button01" android:layout_width="wrap_content" 
07.        android:layout_height="wrap_content" android:text="发送至内部动态注册的BroadcastReceiver"></Button> 
08.    <Button android:id="@+id/Button02" android:layout_width="wrap_content" 
09.        android:layout_height="wrap_content" android:text="发送至内部静态注册BroadcastReceiver"></Button> 
10.    <Button android:id="@+id/Button03" android:layout_width="wrap_content" 
11.        android:layout_height="wrap_content" android:text="发送至系统BroadcastReceiver"></Button> 
12.</LinearLayout> 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas./apk/res/android"
 android:orientation="vertical" android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <Button android:id="@+id/Button01" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:text="发送至内部动态注册的BroadcastReceiver"></Button>
 <Button android:id="@+id/Button02" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:text="发送至内部静态注册BroadcastReceiver"></Button>
 <Button android:id="@+id/Button03" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:text="发送至系统BroadcastReceiver"></Button>
</LinearLayout>
 
testBroadcastReceiver.java的代码如下:
view plaincopy to clipboardprint?
01.package com.testBroadcastReceiver;  
02. 
03.import android.app.Activity;  
04.import android.content.BroadcastReceiver;  
05.import android.content.Context;  
06.import android.content.Intent;  
07.import android.content.IntentFilter;  
08.import android.os.Bundle;  
09.import android.util.Log;  
10.import android.view.View;  
11.import android.widget.Button;  
12.import android.widget.Toast;  
13. 
14.public class testBroadcastReceiver extends Activity {  
15.    Button btnInternal1,btnInternal2,btnSystem;  
16.    static final String INTENAL_ACTION_1 = "com.testBroadcastReceiver.Internal_1";  
17.    static final String INTENAL_ACTION_2 = "com.testBroadcastReceiver.Internal_2";  
18.    static final String INTENAL_ACTION_3 = "com.testBroadcastReceiver.Internal_3";  
19.    @Override 
20.    public void onCreate(Bundle savedInstanceState) {  
21.        super.onCreate(savedInstanceState);  
22.        setContentView(R.layout.main);  
23.        btnInternal1=(Button)this.findViewById(R.id.Button01);  
24.        btnInternal1.setOnClickListener(new ClickEvent());  
25.        btnInternal2=(Button)this.findViewById(R.id.Button02);  
26.        btnInternal2.setOnClickListener(new ClickEvent());  
27.        btnSystem=(Button)this.findViewById(R.id.Button03);  
28.        btnSystem.setOnClickListener(new ClickEvent());  
29.        //动态注册广播消息  
30.        registerReceiver(bcrIntenal1, new IntentFilter(INTENAL_ACTION_1));  
31.    }  
32.    class ClickEvent implements View.OnClickListener{  
33. 
34.        @Override 
35.        public void onClick(View v) {  
36.            if(v==btnInternal1)//给动态注册的BroadcastReceiver发送数据  
37.            {  
38.                Intent intent = new Intent(INTENAL_ACTION_1);  
39.                sendBroadcast(intent);  
40.            }  
41.            else if(v==btnInternal2)//给静态注册的BroadcastReceiver发送数据  
42.            {  
43.                Intent intent = new Intent(INTENAL_ACTION_2);  
44.                sendBroadcast(intent);  
45.            }  
46.            else if(v==btnSystem)//动态注册 接收2组信息的BroadcastReceiver  
47.            {  
48.                IntentFilter filter = new IntentFilter();//  
49.                filter.addAction(Intent.ACTION_BATTERY_CHANGED);//系统电量检测信息  
50.                filter.addAction(INTENAL_ACTION_3);//第三组自定义消息  
51.                registerReceiver(batInfoReceiver, filter);  
52.                  
53.                Intent intent = new Intent(INTENAL_ACTION_3);  
54.                intent.putExtra("Name", "hellogv");  
55.                intent.putExtra("Blog", "http://blog.csdn.net/hellogv");  
56.                sendBroadcast(intent);//传递过去  
57.            }  
58.        }  
59.          
60.    }  
61.      
62.    /* 
63.     * 接收动态注册广播的BroadcastReceiver 
64.     */ 
65.    private BroadcastReceiver bcrIntenal1 = new BroadcastReceiver() {  
66.          
67.        public void onReceive(Context context, Intent intent) {  
68.            String action = intent.getAction();  
69.            Toast.makeText(context, "动态:"+action, 1000).show();  
70.        }  
71.    };  
72.      
73. 
74.    private BroadcastReceiver batInfoReceiver = new BroadcastReceiver() {  
75.          
76.        public void onReceive(Context context, Intent intent) {  
77.            String action = intent.getAction();  
78.            //如果捕捉到的action是ACTION_BATTERY_CHANGED  
79.            if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {  
80.                //当未知Intent包含的内容,则需要通过以下方法来列举  
81.                Bundle b=intent.getExtras();  
82.                Object[] lstName=b.keySet().toArray();  
83. 
84.                for(int i=0;i<lstName.length;i++)  
85.                {  
86.                    String keyName=lstName[i].toString();  
87.                    Log.e(keyName,String.valueOf(b.get(keyName)));  
88.                }  
89.            }  
90.            //如果捕捉到的action是INTENAL_ACTION_3  
91.            if (INTENAL_ACTION_3.equals(action)) {  
92.                //当未知Intent包含的内容,则需要通过以下方法来列举  
93.                Bundle b=intent.getExtras();  
94.                Object[] lstName=b.keySet().toArray();  
95. 
96.                for(int i=0;i<lstName.length;i++)  
97.                {  
98.                    String keyName=lstName[i].toString();  
99.                    Log.e(keyName,b.getString(keyName));  
100.                }  
101.            }  
102.        }  
103.    };  
104. 
105. 
106.} 
package com.testBroadcastReceiver;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class testBroadcastReceiver extends Activity {
    Button btnInternal1,btnInternal2,btnSystem;
    static final String INTENAL_ACTION_1 = "com.testBroadcastReceiver.Internal_1";
    static final String INTENAL_ACTION_2 = "com.testBroadcastReceiver.Internal_2";
    static final String INTENAL_ACTION_3 = "com.testBroadcastReceiver.Internal_3";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnInternal1=(Button)this.findViewById(R.id.Button01);
        btnInternal1.setOnClickListener(new ClickEvent());
        btnInternal2=(Button)this.findViewById(R.id.Button02);
        btnInternal2.setOnClickListener(new ClickEvent());
        btnSystem=(Button)this.findViewById(R.id.Button03);
        btnSystem.setOnClickListener(new ClickEvent());
        //动态注册广播消息
  registerReceiver(bcrIntenal1, new IntentFilter(INTENAL_ACTION_1));
    }
    class ClickEvent implements View.OnClickListener{
  @Override
  public void onClick(View v) {
   if(v==btnInternal1)//给动态注册的BroadcastReceiver发送数据
   {
    Intent intent = new Intent(INTENAL_ACTION_1);
    sendBroadcast(intent);
   }
   else if(v==btnInternal2)//给静态注册的BroadcastReceiver发送数据
   {
    Intent intent = new Intent(INTENAL_ACTION_2);
    sendBroadcast(intent);
   }
   else if(v==btnSystem)//动态注册 接收2组信息的BroadcastReceiver
   {
    IntentFilter filter = new IntentFilter();//
          filter.addAction(Intent.ACTION_BATTERY_CHANGED);//系统电量检测信息
          filter.addAction(INTENAL_ACTION_3);//第三组自定义消息
    registerReceiver(batInfoReceiver, filter);
    
    Intent intent = new Intent(INTENAL_ACTION_3);
    intent.putExtra("Name", "hellogv");
    intent.putExtra("Blog", "http://blog.csdn.net/hellogv");
    sendBroadcast(intent);//传递过去
   }
  }
     
    }
   
    /*
     * 接收动态注册广播的BroadcastReceiver
     */
 private BroadcastReceiver bcrIntenal1 = new BroadcastReceiver() {
  
  public void onReceive(Context context, Intent intent) {
   String action = intent.getAction();
   Toast.makeText(context, "动态:"+action, 1000).show();
  }
 };
 
 private BroadcastReceiver batInfoReceiver = new BroadcastReceiver() {
  
  public void onReceive(Context context, Intent intent) {
   String action = intent.getAction();
   //如果捕捉到的action是ACTION_BATTERY_CHANGED
   if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
    //当未知Intent包含的内容,则需要通过以下方法来列举
    Bundle b=intent.getExtras();
    Object[] lstName=b.keySet().toArray();
    for(int i=0;i<lstName.length;i++)
    {
     String keyName=lstName[i].toString();
     Log.e(keyName,String.valueOf(b.get(keyName)));
    }
   }
   //如果捕捉到的action是INTENAL_ACTION_3
   if (INTENAL_ACTION_3.equals(action)) {
    //当未知Intent包含的内容,则需要通过以下方法来列举
    Bundle b=intent.getExtras();
    Object[] lstName=b.keySet().toArray();
    for(int i=0;i<lstName.length;i++)
    {
     String keyName=lstName[i].toString();
     Log.e(keyName,b.getString(keyName));
    }
   }
  }
 };

}
clsReceiver2.java的代码如下:
view plaincopy to clipboardprint?
01.package com.testBroadcastReceiver;  
02. 
03.import android.content.BroadcastReceiver;  
04.import android.content.Context;  
05.import android.content.Intent;  
06.import android.widget.Toast;  
07. 
08./* 
09. * 接收静态注册广播的BroadcastReceiver, 
10. * step1:要到AndroidManifest.xml这里注册消息 
11. *      <receiver android:name="clsReceiver2"> 
12.            <intent-filter> 
13.                <action 
14.                    android:name="com.testBroadcastReceiver.Internal_2"/> 
15.            </intent-filter> 
16.        </receiver> 
17.    step2:定义消息的字符串 
18.    step3:通过Intent传递消息来驱使BroadcastReceiver触发 
19. */ 
20.public class clsReceiver2 extends BroadcastReceiver{  
21.    @Override 
22.    public void onReceive(Context context, Intent intent) {  
23.        String action = intent.getAction();  
24.        Toast.makeText(context, "静态:"+action, 1000).show();  
25.          
26.    }  
27.} 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hellogv/archive/2010/11/10/5999170.aspx

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多