BroadcastReceiver详解

2、注册相关

 

一、静态注册实例程序 

你们可能会问,什么叫静态注册实例程序,先不要管上面的标题,慢慢往下看,后面在讲动态注册时会再提到。html

先构造一个接收器:java

 

[java] view plain copyandroid

  1. public class MyReceiver extends BroadcastReceiver {  
  2.   
  3.     private static final String TAG = "MyReceiver";    
  4.       
  5.     @Override  
  6.     public void onReceive(Context context, Intent intent) {  
  7.         // TODO Auto-generated method stub  
  8.   
  9.         String msg = intent.getStringExtra("msg");    
  10.         Log.i(TAG, "MyReceiver:"+msg);    
  11.           
  12.     }  
  13.   
  14. }  

直 接派生自BroadcastReceiver,在OnReceive()函数中进行处理便可,咱们前面说了,广播的传递是靠Intent 的,OnReceive的第二个参数,就是广播传过来的Intent,由于后面咱们在发送广播时,会利用PutStringExtra放进去一个标识为 msg的字符串,因此这里咱们能够利用GetStringExtra把这个字符串取出来。而后用Log标记下这个类接收到了这个消息,以便咱们跟踪。
你们可能会想,就这么着,就能收到广播了?固然不是,上面咱们说了,经过隐式Intent来发送广播的,咱们确定要匹配这个Intent啊,匹配Intent的术语是Activity中的,在广播这里,叫要注册,也就是要注册一下,什么样的Intent能接收。app

 

MyReceiver的广播接收 注册代码以下:(静态注册)less

  1. <receiver android:name=".MyReceiver">  
  2.     <intent-filter>  
  3.         <action android:name="android.intent.action.MY_BROADCAST"/>  
  4.         <category android:name="android.intent.category.DEFAULT" />  
  5.     </intent-filter>  
  6. </receiver>  

android:name:对应接收器的类名;咱们自定义的类名叫MyReceiver ,因此这里写".MyReceiver "async

 

intent-filter标签里,一样是必须的两项:action和category;我在这里自定义了action的名字,等下隐式发送经过时,就是利用匹配action来接收通知的。ide

此时的AndroidManifest.xml所有内容为:函数

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.example.test_brocast_blog"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="14"  
  9.         android:targetSdkVersion="14" />  
  10.   
  11.     <application  
  12.         android:allowBackup="true"  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/AppTheme" >  
  16.         <activity  
  17.             android:name=".MainActivity"  
  18.             android:label="@string/app_name" >  
  19.             <intent-filter>  
  20.                 <action android:name="android.intent.action.MAIN" />  
  21.   
  22.                 <category android:name="android.intent.category.LAUNCHER" />  
  23.             </intent-filter>  
  24.         </activity>  
  25.           
  26.         <receiver android:name=".MyReceiver">  
  27.             <intent-filter>  
  28.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  29.                 <category android:name="android.intent.category.DEFAULT" />  
  30.             </intent-filter>  
  31.         </receiver>  
  32.     </application>  
  33.   
  34. </manifest>  

这里特别注意一个<activity> 标签与<receiver>标签的构造。彻底相同!!!!!!!
彻底相同体如今:布局

 

 

  • 一、所处位置:都直属<application>标签;
  • 二、参数构造基本同样;都有android:name,都有<intent-filter>;
  • 三、都是经过Intent传递参数,也都是经过Intent进行匹配!!!!

 

这说明了一个问题:receiver是activity的变种!!!!!我没有研究源码,但仅从这些相同点来看,他们确定是从一个共同的类派生出来的。(猜测)测试

最后是发送广播:

咱们在主页面加一个Button,当点击Button时发送广播消息。

布局文件以下:(activity_main.xml)

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     tools:context="com.example.test_brocast_blog.MainActivity" >  
  6.   
  7.    <Button  
  8.         android:id="@+id/sent_btn"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="发送Broadcast" />  
  12.   
  13. </RelativeLayout>  

代码以下:(MainActivity.java)

  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.       
  8.         Button btn= (Button)findViewById(R.id.sent_btn);  
  9.         btn.setOnClickListener(new View.OnClickListener() {  
  10.               
  11.             @Override  
  12.             public void onClick(View v) {  
  13.                 // TODO Auto-generated method stub  
  14.                 send();  
  15.             }  
  16.         });  
  17.           
  18.     }  
  19.       
  20.     public void send() {  
  21.         Intent intent = new Intent("android.intent.action.MY_BROADCAST");  
  22.         intent.putExtra("msg", "hello receiver.");  
  23.         sendBroadcast(intent);  
  24.     }  
  25. }  

真 正的发送代码在send()函数中,在这个函数中能够看到,咱们经过传进去刚才注册的MyRecevier的action,来构造一个隐式Intent, 而后利用PutExtra放进去一个额外信息(这个不是必须的,咱们仅仅是为了跟踪这个消息传到了哪里去,在《详解Intnent》系统文章中有讲怎样构 造一个隐式Intent),与StartActivity不一样的是,这里利用的是sendBroadcast(intent)来发送这个Intent;
效果图:

这里注意一下应用名!!!!(com.example.test_brocast_blog)后面会用到。

 

二、动态注册实例程序

前面,咱们说了静态注册,什么叫静态注册呢,就是利用XML来注册。

相反,利用代码来注册的就叫动态注册。

静态注册和动态注册是有区别的,主要体如今接收上。

静态注册的程序,不管该程序是否启动,都会当广播到来时接收,并处理。而动态注册的程序只有在程序运行时才会收到广播消息,程序不运行了,它就收不到了。

动态注册的代码以下:

  1. MyReceiver receiver = new MyReceiver();  
  2. IntentFilter filter = new IntentFilter();  
  3. filter.addAction("android.intent.action.MY_BROADCAST");  
  4.           
  5. registerReceiver(receiver, filter);  

同 样,首先生成咱们要接收的类的实例,而后利用IntentFilter来声明他能够匹配的广播类型(这里利用动做来匹配),最后利用 registerReceiver(receiver, filter);来注册,即利用当哪一种类型的Intent广播到来时,要调用MyReceiver类。

 

注意:发送广播以前,要先注册,否则根本没有接收者匹配,固然,不注册接收者也不会出现任何错误或警告,只是发送一个没有任何接收者的广播播毫无心义。
下面咱们新建一个项目,取名叫:Test_Brocast_Blog_Dynamic

一样,写一个MyRecever类来接收广播,MyRecever类内容不变:

  1. public class MyReceiver extends BroadcastReceiver {  
  2.   
  3.     private static final String TAG = "MyReceiver";    
  4.       
  5.     @Override  
  6.     public void onReceive(Context context, Intent intent) {  
  7.         // TODO Auto-generated method stub  
  8.   
  9.         String msg = intent.getStringExtra("msg");    
  10.         Log.i(TAG, msg);    
  11.     }  
  12.   
  13. }  

而后一样,给MainActivity布局里添加一个Button,当点击Button时发送广播。布局文件与上面同样,这里我只写代码:

  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.           
  8.       //在发送以前,肯定在代码的某个位置已经动态注册  
  9.         MyReceiver receiver = new MyReceiver();  
  10.         IntentFilter filter = new IntentFilter();  
  11.         filter.addAction("android.intent.action.MY_BROADCAST");  
  12.                   
  13.         registerReceiver(receiver, filter);  
  14.           
  15.           
  16.         //发送广播  
  17.         Button btn= (Button)findViewById(R.id.sent_btn);  
  18.         btn.setOnClickListener(new View.OnClickListener() {  
  19.               
  20.             @Override  
  21.             public void onClick(View v) {  
  22.                 // TODO Auto-generated method stub  
  23.                 send();  
  24.             }  
  25.         });  
  26.           
  27.           
  28.           
  29.     }  
  30.       
  31.     public void send() {  
  32.         Intent intent = new Intent("android.intent.action.MY_BROADCAST");  
  33.         intent.putExtra("msg", "hello receiver.");  
  34.         sendBroadcast(intent);  
  35.     }  
  36.   
  37. }  

在OnCreate()里在注册广播接收者,即告诉系统,当这个广播到来时,用MyReciver来接收。而后点击发送按钮来发送广播。
注:(在运行这个程序以前,先把静态注册的APP装到手机上,这是下面得出结论的前提)

结果以下:

                                操做界面 

结果:

咦?怎么出来两条信息?

也就是说有两个接收者接收到了这条广播,但咱们这里只注册了一个MyRecever实例啊。

对的,看应用名称就能够看得出,这是两个不一样的应用,有一个是静态注册的(com.example.test_brocast_blog),因此静态注册的程序不论是否启动,均可以收获得匹配的广播的,并对这个广播操做。

若是想试一下,动态注册的代码能不能收到广播,能够反过来一下,运行静态注册的程序,把动态注册的程序关掉,看出来几条Log?答案确定是一条!由于咱们都知道动态注册的代码在程序不运行时是收不到广播的。

 

3、普通广播与有序广播

普通广播是指你们等级都是同样的,当广播到来时,都能一块接收到,并无接收的前后顺序。因为是一同接收到的,因此一个接收者是没有办法阻止另外一个接收者接收这个广播的。

有序广播是指接收是按必定的优先级顺序来接收的,优先级高的先收到,并能够对广播进行操做后,再传给下一个接收者,固然也能够不传,若是不传的话,后面的接收者就都收不到这个广播了。

普通广播

(在运行这个程序以前,先把手机上前两个APP所有删除,以避免影响结果)

首先咱们建三个接收者,并对他们所有静态注册。三个接收者的代码分别以下:

FirstRecever:

  1. public class FirstRecever extends BroadcastReceiver {  
  2.   
  3.     private static final String TAG = "MyReceiver";    
  4.     @Override  
  5.     public void onReceive(Context context, Intent intent) {  
  6.         // TODO Auto-generated method stub  
  7.   
  8.         String msg = intent.getStringExtra("msg");    
  9.         Log.i(TAG, "FirstRecever:"+msg);    
  10.     }  
  11. }  

SecondRecever:

  1. public class SecondRecever extends BroadcastReceiver {  
  2.   
  3.     private static final String TAG = "MyReceiver";    
  4.     @Override  
  5.     public void onReceive(Context context, Intent intent) {  
  6.         // TODO Auto-generated method stub  
  7.   
  8.         String msg = intent.getStringExtra("msg");    
  9.         Log.i(TAG, "SecondRecever:"+msg);    
  10.     }  
  11. }  

 

MyReceiver

  1. public class MyReceiver extends BroadcastReceiver {  
  2.   
  3.     private static final String TAG = "MyReceiver";    
  4.       
  5.     @Override  
  6.     public void onReceive(Context context, Intent intent) {  
  7.         // TODO Auto-generated method stub  
  8.   
  9.         String msg = intent.getStringExtra("msg");    
  10.         Log.i(TAG, "MyReceiver:"+msg);    
  11.     }  
  12. }  

注册代码以下:(AndroidManifest.xml)

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.example.test_brodcast"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="14"  
  9.         android:targetSdkVersion="14" />  
  10.   
  11.     <application  
  12.         android:allowBackup="true"  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/AppTheme" >  
  16.         <activity  
  17.             android:name=".MainActivity"  
  18.             android:label="@string/app_name" >  
  19.             <intent-filter>  
  20.                 <action android:name="android.intent.action.MAIN" />  
  21.   
  22.                 <category android:name="android.intent.category.LAUNCHER" />  
  23.             </intent-filter>  
  24.               
  25.         </activity>  
  26.         <!-- 分别注册这三个接收器 -->  
  27.          <receiver android:name=".MyReceiver">  
  28.             <intent-filter>  
  29.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  30.                 <category android:name="android.intent.category.DEFAULT" />  
  31.             </intent-filter>  
  32.         </receiver>  
  33.           
  34.          <receiver android:name=".FirstRecever">  
  35.             <intent-filter>  
  36.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  37.                 <category android:name="android.intent.category.DEFAULT" />  
  38.             </intent-filter>  
  39.         </receiver>  
  40.           
  41.          <receiver android:name=".SecondRecever">  
  42.             <intent-filter>  
  43.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  44.                 <category android:name="android.intent.category.DEFAULT" />  
  45.             </intent-filter>  
  46.         </receiver>  
  47.           
  48.     </application>  
  49.   
  50. </manifest>  

一样,咱们在MainActivity中添加一个Button,当点击按钮时发送广播,MainActivity代码以下:

  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.           
  8.         Button btn= (Button)findViewById(R.id.sent_btn);  
  9.         btn.setOnClickListener(new View.OnClickListener() {  
  10.               
  11.             @Override  
  12.             public void onClick(View v) {  
  13.                 // TODO Auto-generated method stub  
  14.                 send();  
  15.             }  
  16.         });  
  17.           
  18.     }  
  19.       
  20.     public void send() {  
  21.         Intent intent = new Intent("android.intent.action.MY_BROADCAST");  
  22.         intent.putExtra("msg", "hello receiver.");  
  23.         sendBroadcast(intent);  
  24.     }  
  25.   
  26. }  

运行程序,结果:

可见,三个全都收到了广播。

 

有序广播(无访问权限版)

首先有序广播与普通广播的不一样点在发送和接收都有不一样。

首在发送有序广播:

  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.       
  8.         Button btn= (Button)findViewById(R.id.sent_btn);  
  9.         btn.setOnClickListener(new View.OnClickListener() {  
  10.               
  11.             @Override  
  12.             public void onClick(View v) {  
  13.                 // TODO Auto-generated method stub  
  14.                 send();  
  15.             }  
  16.         });  
  17.           
  18.     }  
  19.       
  20.     public void send() {  
  21.           
  22.         Intent intent = new Intent("android.intent.action.MY_BROADCAST");    
  23.         intent.putExtra("msg", "hello receiver.");    
  24.         sendOrderedBroadcast(intent, null);  //没有添加权限  
  25.     }  
  26. }  

在前面的各个例子中,咱们发送广播都是用的:sendBroadcast(intent); 而这里却用的是:sendOrderedBroadcast(intent, null); 

对这个函数的官方解释是:

public abstract void sendOrderedBroadcast (Intent intent, String receiverPermission)

Added in API level 1

Broadcast the given intent to all interested BroadcastReceivers, delivering them one at a time to allow more preferred receivers to consume the broadcast before it is delivered to less preferred receivers. This call is asynchronous; it returns immediately, and you will continue executing while the receivers are run.

See BroadcastReceiver for more information on Intent broadcasts.

Parameters
intent The Intent to broadcast; all receivers matching this Intent will receive the broadcast.
receiverPermission (optional) String naming a permissions that a receiver must hold in order to receive your broadcast. If null, no permission is required.

其中第二个参数是指定接收者必须拥有的接收权限,若是设为NUll,就是不须要接收权限,全部匹配的Receiver都能接收到。咱们这里先不须要权限试试看,下面再举个须要权限的例子。
接收端

 

咱们上面说了,接收端必须是有序的,是有优先级的,这种优先级是在注册时配置的,好比:

  1. <receiver android:name=".FirstRecever">  
  2. <intent-filter android:priority="10">  
  3.     <action android:name="android.intent.action.MY_BROADCAST"/>  
  4.     <category android:name="android.intent.category.DEFAULT" />  
  5. </intent-filter>  
  6. lt;/receiver>  

与上面静态注册的不一样在于,在Intent-filter中添加一个android:priority="10"属性,这个就是接收器优先级,数字越大的接收器,优先级越高,越先接到广播。
一样,上面咱们三个类FirstRecever、SecondRecever和MyReceiver 的注册文件代码以下 :

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.example.testbroast_order"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="14"  
  9.         android:targetSdkVersion="14" />  
  10.   
  11.     <application  
  12.         android:allowBackup="true"  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/AppTheme" >  
  16.         <activity  
  17.             android:name=".MainActivity"  
  18.             android:label="@string/app_name" >  
  19.             <intent-filter>  
  20.                 <action android:name="android.intent.action.MAIN" />  
  21.   
  22.                 <category android:name="android.intent.category.LAUNCHER" />  
  23.             </intent-filter>  
  24.         </activity>  
  25.           
  26.   
  27.          <receiver android:name=".FirstRecever">  
  28.             <intent-filter android:priority="10">  
  29.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  30.                 <category android:name="android.intent.category.DEFAULT" />  
  31.             </intent-filter>  
  32.         </receiver>  
  33.           
  34.          <receiver android:name=".SecondRecever">  
  35.             <intent-filter android:priority="9">  
  36.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  37.                 <category android:name="android.intent.category.DEFAULT" />  
  38.             </intent-filter>  
  39.         </receiver>  
  40.           
  41.         <receiver android:name=".MyReceiver">  
  42.             <intent-filter android:priority="8">  
  43.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  44.                 <category android:name="android.intent.category.DEFAULT" />  
  45.             </intent-filter>  
  46.         </receiver>  
  47.         <!-- 接收优先级逐级下降 -->  
  48.     </application>  
  49.   
  50. </manifest>  

最后是代码部分
前面我也曾提到,在一个接收器收到发来的Intent后,能够对其进行更改,对发送来的广播Intent进行修改是利用setResultExtras(bundle);  函数来实现的。

 

public final void setResultExtras (Bundle extras)

Added in API level 1

Change the current result extras of this broadcast; only works with broadcasts sent through Context.sendOrderedBroadcast. This is a Bundle holding arbitrary data, whose interpretation is up to the broadcaster. Can be set to null. Calling this method completely replaces the current map (if any).

This method does not work with non-ordered broadcasts such as those sent with Context.sendBroadcast

Parameters
extras The new extra data map; may be null.

翻译一下:

这个函数是用来改变当前广播传来的Extra额外信息的;它只能经过Context.sendOrderedBroadcast.发送过来的广播有效;它使用Bundle来传递任意的数据,而这些数据只有接收器(broadcaster)才能解析。固然也能够把它设置为NULL,这样,它就把传来的数据映射所有清空了。

参数:

extras:新的数据映射,能够为空。

从上面的优先级能够看出,这里三个类的接收顺序是这样的:FirstRecever-》SecondRecever-》MyReceiver

下面看看FirstRecever如何利用setResultExtras来改变传来的Msg信息:

  1. public class FirstRecever extends BroadcastReceiver {  
  2.   
  3.     private static final String TAG = "MyReceiver";    
  4.     @Override  
  5.     public void onReceive(Context context, Intent intent) {  
  6.         // TODO Auto-generated method stub  
  7.   
  8.         //先得到传过来的MSG  
  9.         String msg = intent.getStringExtra("msg");    
  10.         Log.i(TAG, "FirstRecever:"+msg);    
  11.           
  12.         //更改广播数据  
  13.          Bundle bundle = new Bundle();    
  14.          bundle.putString("msg", msg + "@FirstReceiver");    
  15.          setResultExtras(bundle);    
  16.     }  
  17. }  

首先,咱们利用getStringExtra()得到传过来的msg消息,而后利用bundle从新封装一个以“msg”为key的消息,把"@FirstReceiver"添加到消息里,表示通过了这里。

最后利用setResultExtras(bundle);  修改当前的结果集。

若是想终止消息往下一个接收器传递,可使用:abortBroadcast();  //终止消息再传递

这里有一个疑问:我利用setResultExtras(bundle); 修改传送结果,对原来广播过来的数据有影响吗?下面咱们就在SecondRecever中作个测试

 

下面看看另外两个接收器代码:SecondRecever

  1. public class SecondRecever extends BroadcastReceiver {  
  2.   
  3.     private static final String TAG = "MyReceiver";    
  4.     @Override  
  5.     public void onReceive(Context context, Intent intent) {  
  6.         // TODO Auto-generated method stub          
  7.        
  8.        //先得到广播过来的MSG  
  9.         String broadcast_msg = intent.getStringExtra("msg");    
  10.         Log.i(TAG, "SecondRecever--broadcast_msg:"+broadcast_msg);    
  11.           
  12.         //接收经过setResultExtras传过来的msg  
  13.         String msg = getResultExtras(true).getString("msg");    
  14.         Log.i(TAG, "SecondReceiver: " + msg);    
  15.           
  16.         //修改setResultExtras传来的结果  
  17.         Bundle bundle = new Bundle();    
  18.         bundle.putString("msg", msg + "@SecondReceiver");    
  19.         setResultExtras(bundle);    
  20.     }  
  21. }  

这里先经过intent.getStringExtra("msg");  得到广播过来的数据;

 

而后再利用getResultExtras(true).getString("msg");  得到上一级传过来的setResultExtras(bundle);  里的数据;
最后从新将bundle里的数据中添加"@SecondReceiver"作个标记;

最后,MyReceiver:

  1. public class MyReceiver extends BroadcastReceiver {  
  2.   
  3.     private static final String TAG = "MyReceiver";    
  4.       
  5.     @Override  
  6.     public void onReceive(Context context, Intent intent) {  
  7.         // TODO Auto-generated method stub  
  8.   
  9.         String msg = getResultExtras(true).getString("msg");    
  10.         Log.i(TAG, "MyReceiver: " + msg);    
  11.     }  
  12. }  

 

到这就全部就序了,运行下代码:

从结果能够看出:经过setResultExtras(bundle);  传递的数据是不会更改原生广播的数据的。也只是原来广播数据中额外添加的数据。

 

有序广播(添加访问权限版)

前面咱们看到在sendOrderedBroadcast(intent, null);  中,第二个参数能够设定访问权限,在上个例子中,咱们并无加入访问权限,下面咱们就发送一个带权限的广播:

  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.   
  8.         Button btn= (Button)findViewById(R.id.sent_btn);  
  9.         btn.setOnClickListener(new View.OnClickListener() {  
  10.               
  11.             @Override  
  12.             public void onClick(View v) {  
  13.                 // TODO Auto-generated method stub  
  14.                 send();  
  15.             }  
  16.         });  
  17.           
  18.     }  
  19.       
  20.     public void send() {  
  21.           
  22.         Intent intent = new Intent("android.intent.action.MY_BROADCAST");    
  23.         intent.putExtra("msg", "hello receiver.");    
  24.         sendOrderedBroadcast(intent, "harvic.broadcast.perssion");   
  25.     }  
  26. }  

这段代码中,咱们利用 sendOrderedBroadcast(intent, "harvic.broadcast.perssion"); 发送一个必须拥有"harvic.broadcast.perssion"权限的接收器才能接收到咱们的广播;
而后咱们要在接收器中加入声明使用权限的代码:

 

有关权限的声明与使用,能够参考这篇文章:《声明、使用与自定义权限》

首先建立一个"harvic.broadcast.perssion"权限

  1. <permission android:name="harvic.broadcast.perssion" android:protectionLevel="normal"></permission>   

而后是底部声明,咱们要使用这个权限:

  1. <uses-permission  android:name="harvic.broadcast.perssion"/>  

因此整体的代码以下:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.example.testbroadcast_order_perssion"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="14"  
  9.         android:targetSdkVersion="14" />  
  10.     <permission android:name="harvic.broadcast.perssion" android:protectionLevel="normal"></permission>   
  11.   
  12.     <application  
  13.         android:allowBackup="true"  
  14.         android:icon="@drawable/ic_launcher"  
  15.         android:label="@string/app_name"  
  16.         android:theme="@style/AppTheme" >  
  17.         <activity  
  18.             android:name=".MainActivity"  
  19.             android:label="@string/app_name" >  
  20.             <intent-filter>  
  21.                 <action android:name="android.intent.action.MAIN" />  
  22.   
  23.                 <category android:name="android.intent.category.LAUNCHER" />  
  24.             </intent-filter>  
  25.         </activity>  
  26.           
  27.           
  28.         <receiver android:name=".FirstRecever" >  
  29.             <intent-filter android:priority="10">  
  30.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  31.                 <category android:name="android.intent.category.DEFAULT" />  
  32.             </intent-filter>  
  33.         </receiver>  
  34.           
  35.          <receiver android:name=".SecondRecever" >  
  36.             <intent-filter android:priority="9">  
  37.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  38.                 <category android:name="android.intent.category.DEFAULT" />  
  39.             </intent-filter>  
  40.         </receiver>  
  41.           
  42.         <receiver android:name=".MyReceiver" >  
  43.             <intent-filter android:priority="8">  
  44.                 <action android:name="android.intent.action.MY_BROADCAST"/>  
  45.                 <category android:name="android.intent.category.DEFAULT" />  
  46.             </intent-filter>  
  47.         </receiver>  
  48.         <!-- 接收优先级逐级下降 -->  
  49.           
  50.     </application>  
  51.      
  52.     <!-- 若是不添加使用权限声明,那么接收器会拒绝接受消息的,因此在Log中不会有任何显示 -->  
  53.     <uses-permission  android:name="harvic.broadcast.perssion"/>  
  54.   
  55. </manifest>  

其它接收器代码不变,运行以后:

 


有 个地方要注意:即使像咱们如今这样,本身的应用发出广播给本身接收,但若是不声明使用权限,是不能接收到广播的。这点与Activity的权限机制不一 样,在Activity中,只要在同一个应用中相互App跳转,是不须要声明使用权限的,权限的限制只针对其它应用调用此Activity。
 

好啦,这篇文章到这就结束了。本篇内容比较多,涉及到的代码工程也比较多,现将相关源码列表以下:

一、静态注册源码
二、动态注册源码
三、普通接收源码
四、有序广播(无访问权限)源码
五、有序广播(添加访问权限)源码
六、本文所用图片

 

注意:在OnReceive中保存传过来值的问题:

若是有下面一段伪代码:

class xxxx{

private int mData=1;

public void onReceive(Context context, Intent intent)

Log.d("tag",mData + "");

mData = intent.getIntExtra("intdata",-1);

}

若是咱们经过intent传过来的值保存在mData中,在下次再来的时候先打出来mData的值,会发现,每次打出来的都是1,因此根本没有办法经过成员变量保存onReceive中传过来的值。

相关文章
相关标签/搜索