android broadcast sendOrderedBroadcast

http://blog.csdn.net/zhongnan09/article/details/6552632

广播接收器:

 

广播接收者(BroadcastReceiver)用于监听系统事件或应用程序事件,通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()可以向系统发送广播意图,通过广播一个意图(Intent)可以被多个广播接收者所接收,从而可以在不用修改原始的应用程序的情况下,让你对事件作出反应。

       其中Context.sendBroad()主要是用来广播无序事件(也被称为有序广播 Normal broadcast),即所有的接收者在理论上是同时接收到事件,同时执行的,对消息传递的效率而言这是比较好的做法。而Context.sendOrderedBroadcast()方法用来向系统广播有序事件(Ordered broadcast),接收者按照在Manifest.xml文件中设置的接收顺序依次接收Intent,顺序执行的,接收的优先级可以在系统配置文件中设置(声明在intent-filter元素的android:priority属性中,数值越大优先级别越高,其取值范围为-1000到1000。当然也可以在调用IntentFilter对象的setPriority()方法进行设置)。对于有序广播而言,前面的接收者可以对接收到得广播意图(Intent)进行处理,并将处理结果放置到广播意图中,然后传递给下一个接收者,当然前面的接收者有权终止广播的进一步传播。如果广播被前面的接收者终止后,后面的接收器就再也无法接收到广播了。

 

广播接收器(Broadcaset)运行的线程:

       无论对于有序广播还是无序广播,广播接收器默认都是运行在主线程中的(main线程,即UI线程)。可以通过在程序中使用registerReceiver(receiver, filter, broadcastPermission, scheduler)方法中的最后一个参数指定要运行的广播接收器的线程。也可以在Manifest.xml文件中设置(Intent-filter标签中设置android:process)。

 

无序广播(Normal Broadcast)

       基本步骤:写一个类继承BroadcastReceiver,并重写onReceive方法,而后在AndroidManifest.xml文中中进行配置,或者直接在代码中注册。

      

下面是一个广播接收器的Demo(用于发送和接收短信):

      

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.telephony.SmsMessage;

import android.util.Log;

 

public class ReceivingSMSReceiver extends BroadcastReceiver
{

    private static final String SMS_RECEIVED ="android.provider.Telephony.SMS_RECEIVED";

    private static final String TAG = "ReceivingSMSReceiver";

 

    @Override

    public void onReceive(Context
context, Intent intent) {

       if (intent.getAction().equals(SMS_RECEIVED))
{

           Bundle bundle = intent.getExtras();

           if (bundle != null)
{

              Object[] pdus = (Object[]) bundle.get("pdus");

              SmsMessage[] messages = new SmsMessage[pdus.length];

              for (int i
= 0; i < pdus.length; i++)

                  messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);

              for (SmsMessage message : messages) {

                  String msg = message.getMessageBody();

                  Log.i(TAG, msg);

                  String to = message.getOriginatingAddress();

                  Log.i(TAG, to);

              }

           }

       }

    }

}

 

在AndroidManifest.xml文件中的<application>节点里对接收到短信的广播Intent进行注册:

<receiver android:name=". ReceivingSMSReceiver">

<intent-filter>

<action android:name="android.provider.Telephony.SMS_RECEIVED"/>

</intent-filter>

</receiver>

在AndroidManifest.xml文件中添加以下权限:

<uses-permission android:name="android.permission.RECEIVE_SMS"/><!-- 接收短信权限 -->

 

该广播接收器将首先得到本机收到的短信,可以对短信内容进行过滤。

 

在模拟器中运行该工程。

 

建立一个新的Android工程,新建一个Activity用来发送短信:

 

import android.app.Activity;

import android.app.PendingIntent;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.telephony.SmsManager;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

 

public class SMSSender extends Activity
{

    private static final String TAG = "SMSSender";

    Button send = null;

    EditText address = null;

    EditText content = null;

    private mServiceReceiver mReceiver01, mReceiver02;

    private static String SEND_ACTIOIN = "SMS_SEND_ACTION";

    private static String DELIVERED_ACTION = "SMS_DELIVERED_ACTION";

 

    @Override

    protected void onCreate(Bundle
savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);

       address = (EditText) findViewById(R.id.address);

       content = (EditText) findViewById(R.id.content);

       send = (Button) findViewById(R.id.send);

       send.setOnClickListener(new View.OnClickListener()
{

 

           @Override

           public void onClick(View
v) {

              // TODO Auto-generated method
stub

              String mAddress = address.getText().toString().trim();

              String mContent = content.getText().toString().trim();

              if ("".equals(mAddress)
|| "".equals(mContent)) {

                  Toast.makeText(SMSSender.this, "发送地址为空或内容为空!",

                         Toast.LENGTH_LONG).show();

                  return;

              }

              SmsManager smsManager = SmsManager.getDefault();

              try {

                  Intent send_Intent = new Intent(SEND_ACTIOIN);

                  Intent deliver_Intent = new Intent(DELIVERED_ACTION);

                  PendingIntent mSend = PendingIntent.getBroadcast(

                         getApplicationContext(), 0, send_Intent, 0);

                  PendingIntent mDeliver = PendingIntent.getBroadcast(

                         getApplicationContext(), 0, deliver_Intent, 0);

                  smsManager.sendTextMessage(mAddress, null, mContent, mSend,

                         mDeliver);

              } catch (Exception e) {

                  e.printStackTrace();

              }

           }

       });

    }

 

    @Override

    protected void onResume()
{

       // TODO Auto-generated method stub

       IntentFilter mFilter01;

       mFilter01 = new IntentFilter(SEND_ACTIOIN);

       mReceiver01 = new mServiceReceiver();

       registerReceiver(mReceiver01, mFilter01);

       mFilter01 = new IntentFilter(DELIVERED_ACTION);

       mReceiver02 = new mServiceReceiver();

       registerReceiver(mReceiver02, mFilter01);

       super.onResume();

    }

 

    @Override

    protected void onPause()
{

       // TODO Auto-generated method stub

       unregisterReceiver(mReceiver01);

       unregisterReceiver(mReceiver02);

       super.onPause();

    }

 

    public class mServiceReceiver extends BroadcastReceiver
{

       @Override

       public void onReceive(Context
context, Intent intent) {

           // TODO Auto-generated method stub

           if (intent.getAction().equals(SEND_ACTIOIN))
{

              try {

                  switch (getResultCode()) {

                  case Activity.RESULT_OK:

                     break;

                  case SmsManager.RESULT_ERROR_GENERIC_FAILURE:

                     break;

                  case SmsManager.RESULT_ERROR_RADIO_OFF:

                     break;

                  case SmsManager.RESULT_ERROR_NULL_PDU:

                     break;

                  }

              } catch (Exception e) {

                  e.getStackTrace();

              }

           } else if (intent.getAction().equals(DELIVERED_ACTION))
{

              try {

                  switch (getResultCode()) {

                  case Activity.RESULT_OK:

                     break;

                  case SmsManager.RESULT_ERROR_GENERIC_FAILURE:

                     break;

                  case SmsManager.RESULT_ERROR_RADIO_OFF:

                     break;

                  case SmsManager.RESULT_ERROR_NULL_PDU:

                     break;

                  }

              } catch (Exception e) {

                  e.getStackTrace();

              }

           }

       }

    }

}

 

界面布局:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical" android:layout_width="fill_parent"

    android:layout_height="fill_parent">

    <TextView android:layout_width="fill_parent"

       android:layout_height="wrap_content" android:text="发送短信" />

    <TextView android:text="收信人地址:" android:id="@+id/textView1"

       android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>

    <EditText android:text="" android:layout_width="match_parent"

       android:id="@+id/address" android:layout_height="wrap_content"></EditText>

    <TextView android:text="短信内容:" android:id="@+id/textView2"

       android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>

    <EditText android:text="" android:layout_width="match_parent"

       android:id="@+id/content" android:layout_height="wrap_content"></EditText>

    <Button android:text="发送" android:id="@+id/send"

       android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>

</LinearLayout>

 

在AndroidManifest.xml文件中增加对该Activity的配置:

<activity android:name=".SMSSender" android:label="@string/app_name">

           <intent-filter>

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

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

           </intent-filter>

       </activity>

在AndroidManifest.xml文件中添加以下权限:

<uses-permission android:name="android.permission.SEND_SMS"/><!—发送短信权限 -->

 

在另一个模拟器中运行该工程。

 

由于本文的重点内容并不是发送和接收短信,所以,对短信发送和接收的内容并没有详细解释。如果对短信收发内容不熟悉的朋友,可以查阅相关文档。

 

 

有序广播:

 

接收器1:

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

 

public class BroadcastTest2 extends BroadcastReceiver
{

 

    @Override

    public void onReceive(Context
arg0, Intent arg1) {

       System.out.println("运行线程:    " +
Thread.currentThread().getId() + "   "

              + Thread.currentThread().getName());

       System.out.println("广播意图的动作:  " +
arg1.getAction());

       Bundle bundle = new Bundle();

       bundle.putString("test", "zhongnan");

       setResultExtras(bundle);

    }

}

 

接收器2:

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

 

public class BroadcastTest1 extends BroadcastReceiver
{

 

    @Override

    public void onReceive(Context
arg0, Intent arg1) {

       System.out.println("运行线程:    " +
Thread.currentThread().getId() + "   "

              + Thread.currentThread().getName());

       System.out.println("广播意图的动作:  " +
arg1.getAction());

       Bundle bundle = getResultExtras(false);

      

       if (bundle == null)
{

           System.out.println("没有得到上次传递的数据");

       } else {

           System.out.println("测试:  " +
bundle.getString("test"));

       }

    }

}

 

主Activity,用来发送广播:

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

 

public class MainActivity extends Activity
{

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle
savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);

       this.sendOrderedBroadcast(new Intent(

              "android.provier.zhongnan.broadcast"), null);

    }

}

 

AndroidManifest.xml文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.zhongnan.bc" android:versionCode="1" android:versionName="1.0">

    <uses-sdk android:minSdkVersion="8" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">

       <activity android:name=".MainActivity" android:label="@string/app_name">

           <intent-filter>

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

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

           </intent-filter>

       </activity>

       <receiver android:name=".BroadcastTest1">

           <intent-filter>

              <action android:name="android.provier.zhongnan.broadcast"

                  android:priority="400" />

           </intent-filter>

       </receiver>

       <receiver android:name=".BroadcastTest2">

           <intent-filter>

              <action android:name="android.provier.zhongnan.broadcast"

                  android:priority="500" />

           </intent-filter>

       </receiver>

    </application>

</manifest>

 

在MainActivity中发送有序广播Context.sendOrderedBroadcast(),由于BroadcastTest2中设置的接收优先级比较高,所以在BroadcastTest2中将首先接收到广播意图,可以在BroadcastTest2中对该广播意图进行处理,可以加入处理后的数据给后面的接收器使用,也可以在该接收器中终止广播的进一步传递。在广播中加入处理后的数据使用setResultExtras(Bundle
bundle)方法,关于Bundle类,类似于HashMap,不熟悉的朋友可以参考文档,或者查看我的另一篇博客。在后面的接收器中使用getResultExtras(boolean
flag
)接收前面的接收器存放的数据,其中的boolean参数含义为:true代表如果前面的接收器没有存放数据,则自动创建一个空的Bundle对象,false则表示如果前面的接收器如果没有存放任何数据则返回null。

 

广播接收器中权限的定义:

    在发送广播时,无论是无序广播(Normal Broadcast)还是有序广播(Ordered Broadcast)都有类似的方法:sendBroadcast (Intent intent, String receiverPermission), sendOrderedBroadcast (Intent intent, String receiverPermission)。其中第二个参数是设置权限,即接收器必须具有相应的权限才能正常接收到广播。

 

下面是在上述例子的基础上添加自定义权限的例子:

         接收器1:

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

 

public class BroadcastTest2 extends BroadcastReceiver
{

 

    @Override

    public void onReceive(Context
arg0, Intent arg1) {

       System.out.println("运行线程:    " +
Thread.currentThread().getId() + "   "

              + Thread.currentThread().getName());

       System.out.println("广播意图的动作:  " +
arg1.getAction());

       Bundle bundle = new Bundle();

       bundle.putString("test", "zhongnan");

       setResultExtras(bundle);

    }

}

 

接收器2:

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

 

public class BroadcastTest1 extends BroadcastReceiver
{

 

    @Override

    public void onReceive(Context
arg0, Intent arg1) {

       System.out.println("运行线程:    " +
Thread.currentThread().getId() + "   "

              + Thread.currentThread().getName());

       System.out.println("广播意图的动作:  " +
arg1.getAction());

       Bundle bundle = getResultExtras(false);

      

       if (bundle == null)
{

           System.out.println("没有得到上次传递的数据");

       } else {

           System.out.println("测试:  " +
bundle.getString("test"));

       }

    }

}

 

主Activity,用来发送广播:

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

 

public class MainActivity extends Activity
{

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle
savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);

       this.sendOrderedBroadcast(new Intent(

              "android.provier.zhongnan.broadcast"), "xzq.zhongnan.test");

    }

}

代码中与上述例子最大的差别在于MainActivity中发送广播的代码: this.sendOrderedBroadcast(new Intent(

              "android.provier.zhongnan.broadcast"), "xzq.zhongnan.test")增加了自定义的一个权限。

在AndroidManifest文件中配置自定义的权限:

    <permission android:protectionLevel="normal" android:name="xzq.zhongnan.test"></permission>

关于如何在工程中自定义权限请查阅相关文档,或查看我的另一篇博客。

相应的,接收器中必须设置接收权限:

<uses-permission android:name="xzq.zhongnan.test"></uses-permission>

这样,接收器就可以正确接收到广播了。

 

 

 

 

另外,上述程序已讲到,BroadcastReceiver是允许在主线程中的,所以,在onReceive方法中执行的代码,运行时间不能超过5s,否则将报出程序没有相应的异常,如果要执行的代码运行的时间比较长,可以使用Service组件。

时间: 2024-07-28 12:20:49

android broadcast sendOrderedBroadcast的相关文章

Android Broadcast Receiver

说明 有时候我们在做android系统软件的时候,经常会需要做的事就是开机重新设置上次关机前的状态,当然,我们就会用到这个开机广播: <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 利用这个开机广播,我们可以将上次app设置的数据,开机后设置回系统,这样看上去系统就像上次的状态. Demo使用方法 AndroidManifest.xml <manifest xmln

Android基础知识之broadcast广播详解_Android

Android中的广播用的太多了,今天稍微总结一下. 按注册方式分为两种: 1.静态注册广播: 静态注册广播就是在androidManifest.xml文件中注册广播,假设我们要实现这样一个效果,在一个activity上点击按钮,发送一条广播,这条广播弹出一个toast,显示"静态"二字. 先看看广播接受者: public class MyBroadcast extends BroadcastReceiver { @Override public void onReceive(Cont

我的Android进阶之旅】GitHub 上排名前 100 的 Android 开源库进行简单的介绍

GitHub Android Libraries Top 100 简介 本文转载于:https://github.com/Freelander/Android_Data/blob/master/Android-Librarys-Top-100.md 本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍, 至于排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果, 然后过滤了跟 Android 不相关的项目, 所以排名并

Android使用BroadcastReceiver实现手机开机之后显示画面的功能_Android

本文实例讲述了Android使用BroadcastReceiver实现手机开机之后显示画面的功能.分享给大家供大家参考,具体如下: 在此例中介绍了怎样使用BroadcastRececiver.使用BroadcastReceiver需要继承这个类,并且重写public void onReceiver(Context context,Intent intent)这个方法,在这个方法中来添加想要实现的功能. 下面这个例子是实现android手机开机之后,所自动显示的画面,通过ImageView来引入一

Android采取BroadcastReceiver方式自动获取验证码_Android

Android 自动获取验证码的两种方式分别是BroadcastReceiver及ContentObserver,两种方式都需要进行注册.取消注册两个步骤 记得添加权限,本文先介绍其中一种. <uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORA

用代码画流程图和时序图快餐教程(3) - PlantUML画时序图

PlantUML画时序图 用描述性的语言来写UML,尤其是Sequence Diagram,PlantUML应该是很多同学的首选了吧. 网址:http://plantuml.com/ 我们可以使用eclipse的plugin来写PlantUML,如下: 速成教程 @startuml和@enduml 这个没啥说的,开始的时候用@startuml,结束的时候要加个@enduml. 标题 格式: title 标题名 participant 格式:participant 类名 #颜色 例: @start

Android开发四大组件Activity/Service/Broadcast Receiver/Content Provider详解

Android开发的四大组件一.Activity详解二.Service详解三.Broadcast Receiver详解四.Content Provider详解外加一个重要组件 intent的详解. 一.Activity详解 Activty的生命周期的也就是它所在进程的生命周期. 一个Activity的启动顺序: onCreate()-->onStart()-->onResume() 当另一个Activity启动时:第一个Activity onPause()-->第二个Activity  

《Android开发进阶:从小工到专家》——第1章,第1.3节Broadcast(广播)

1.3 Broadcast(广播)Broadcast是一种广泛运用的.在应用程序之间传输信息的机制,Android中的广播与传统意义上的电台广播类似,一个广播可以有任意个接收者.广播机制是一个典型的发布-订阅模式,也就是我们所说的观察者模式.广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的,通过这样的形式来达到接.收双方的完全解耦合. Android广播机制包含 3 个基本要素,分别是用于发送广播的Broadcast.接收广播的BroadcastReceiv

Android中的Intent广播(broadcast)简介

Intent可以使用sendBroadcast(), 在应用组件之间广播事件; 使用BroadReceiver类监听和响应Broadcast Intent, 需要注册(register)和过滤器(intent-filter); 1. 创建Broadcast Intent 构建需要广播的Intent, 包含Intent标识字符串, 和数据(data, extras), 使用sendBroadcast()发送; Intent标识字符串, 可以标识要广播的字符串, 应该是能够标志的唯一字符串, pub