zoukankan      html  css  js  c++  java
  • android菜鸟学习笔记26----Android广播消息及BroadcastReceiver

    1.广播类型

    Android中的广播有两种类型:标准广播和有序广播。其中,标准广播是完全异步发送的广播,发出之后,几乎所有的广播接收者都会在同一时刻收到这条广播消息,因而,这种类型的广播消息是不可拦截,不可修改的;而有序广播是一种同步发送的广播,广播发出后,只有优先级最高的广播接收者能够收到这条广播消息,它处理完自己的逻辑之后,广播才会向后继续传递给低优先级的广播接收者,因此,高优先级的广播接收者可以对广播消息进行拦截,修改操作。

    2.接收系统广播

    要接收系统广播,就要有自己的广播接收者。定义一个自己的广播接收者的方式就是自定义一个类继承自BroadcastReceiver,然后重写其onReceive()方法即可,在onReceive()方法中可以实现广播消息的获取,修改等操作,当然能修改的只有有序广播。

    BroadcastReceiver中的常用方法:

     

    getResultCode()、getResultData()、getResultExtras()分别用来获取广播的代码,数据及附加数据信息,一般是前一个广播接收者所设定的。

     

    setXX()与上面的getXX()对应,用来进行相应的设置,后一个广播接收者获取的将是当前设置的数据。

     

    abortBradcast()截断当前广播。

    2.1接收向外拨号的广播

    1)定义广播接收器并重写onReceive()方法:

     1 public class OutCallingReceiver extends BroadcastReceiver {
     2 
     3       @Override
     4 
     5       public void onReceive(Context context, Intent intent) {
     6 
     7            // TODO Auto-generated method stub
     8 
     9            String number = this.getResultData();
    10 
    11            if(number.equals("10086")){
    12 
    13                  this.setResultData("110");
    14 
    15            }else if(number.equals("10000")){
    16 
    17                  this.setResultData("120");
    18 
    19            }else{
    20 
    21                  this.setResultData("2222");
    22 
    23            }
    24 
    25            Toast.makeText(context, "转发成功", Toast.LENGTH_SHORT).show();
    26 
    27       }
    28 
    29 }

    2)在Manifest.xml清单文件的<application>节点下中注册广播接收者组件,声明其能接收的广播为向外拨号:

    1 <receiver android:name="cn.csc.broadcast.OutCallingReceiver">
    2 
    3             <intent-filter >
    4 
    5                 <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
    6 
    7             </intent-filter>
    8 
    9 </receiver>

    3)由于重写的onReceive()方法中修改了广播,对向外拨出的号码进行了修改,所以需要配置权限:

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

    4)运行结果:

    部署到模拟器后,然后拨号:

     

    被处理之后:

     

    2.2接收网络状态变化的广播:参考《第一行代码》

    1)定义广播接收器并重写onReceive()方法:

     1 public class NetworkReceiver extends BroadcastReceiver {
     2 
     3  
     4 
     5       @Override
     6 
     7       public void onReceive(Context context, Intent intent) {
     8 
     9            // TODO Auto-generated method stub
    10 
    11            ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    12 
    13            NetworkInfo info = connManager.getActiveNetworkInfo();
    14 
    15            if(info != null && info.isAvailable()){
    16 
    17                  Toast.makeText(context, "网络可用", Toast.LENGTH_SHORT).show();
    18 
    19            }else{
    20 
    21                  Toast.makeText(context, "网络不可用", Toast.LENGTH_SHORT).show();
    22 
    23            }
    24 
    25       }
    26 
    27 }

    2)在Manifest.xml清单文件的<application>节点下中注册广播接收者组件:

    1 <receiver android:name="cn.csc.broadcast.NetworkReceiver">
    2 
    3             <intent-filter >
    4 
    5                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
    6 
    7             </intent-filter>
    8 
    9 </receiver>

    3)需要配置权限读取网络状态的权限:

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

    4)运行结果:

    部署到模拟器后,在配置中修改网络状态:

    设置为飞行模式,网络不可用:

     

    关闭飞行模式,网络变为可用:

     

    关闭手机移动网络:

     

    开启手机移动网络:

     

    3.发送广播:

    需要用到Context的以下方法:

     

    sendBroadcast(Intent intent):传入一个意图,然后根据意图发出一个标准广播。

    sendBroadcast(Intent intent, String receiverPermission):传入一个意图及一个字符串表示的权限,指定声明改权限的广播接收者才能收到这个广播,第二个参数为null的话,表示不需要声明权限。

    sendOrderedBroadcast(Intent intent, String receiverPermission):参数含义同上一个方法,不同的是该方法发送一个有序广播。

    sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras):同样是发送一个有序广播,多出来的参数含义如下:

    resultReceiver:指定最终的接收者,不需要则设为null

    scheduler:指定自定义的Handler执行resultReceiver的回调,null则在主线程执行

    initalCode:为resultCode设置初始值

    initalData:为resultData设置初始值

    initalExtras:为resultExtras设置初始值

    3.1发送标准广播

    1)修改应用的Activity,添加一个按钮,按钮的单击响应监听中发送自定义广播:

     1 Button btn = (Button) findViewById(R.id.btn_send_normal);
     2 
     3         btn.setOnClickListener(new OnClickListener() {
     4 
     5                 
     6 
     7                  @Override
     8 
     9                  public void onClick(View v) {
    10 
    11                       // TODO Auto-generated method stub
    12 
    13                       Intent intent = new Intent("cn.csc.broadcast.PARTY");
    14 
    15                       intent.putExtra("content", "明天下午16点校南门集合,一起去龙湖看电影,聚餐");
    16 
    17                       sendBroadcast(intent);
    18 
    19                  }
    20 
    21            });

    2)自定义广播接收器,接收自己发送的聚餐广播:

     1 public class PartyReceiver extends BroadcastReceiver {
     2 
     3       @Override
     4 
     5       public void onReceive(Context context, Intent intent) {
     6 
     7            // TODO Auto-generated method stub
     8 
     9            Toast.makeText(context, intent.getStringExtra("content"), Toast.LENGTH_LONG).show();
    10 
    11       }
    12 
    13 }

    3)在清单文件中,配置PartyReceiver:

    1 <receiver android:name="cn.csc.broadcast.PartyReceiver">
    2 
    3             <intent-filter >
    4 
    5                 <action android:name="cn.csc.broadcast.PARTY"/>
    6 
    7             </intent-filter>
    8 
    9 </receiver>

    4)运行结果:

     

    3.2发送有序广播:

    1)修改按钮单击事件监听:

    sendOrderedBroadcast(intent, null, null, null, 0, "明天下午16点校南门集合,一起去龙湖看电影,聚餐", null);

    2)新建几个接收聚餐广播的接收者:

    可以直接复制原来的那个,简单修改标识即可,采用Logcat输出消息:

     1 public class PartyReceiver1 extends BroadcastReceiver {
     2 
     3       @Override
     4 
     5       public void onReceive(Context context, Intent intent) {
     6 
     7            // TODO Auto-generated method stub
     8 
     9            Log.i("PARTY","F1:"+ getResultData());
    10 
    11       }
    12 
    13 }

    3)在清单文件中注册:

     1 <receiver android:name="cn.csc.broadcast.PartyReceiver1">
     2 
     3             <intent-filter >
     4 
     5                 <action android:name="cn.csc.broadcast.PARTY"/>
     6 
     7             </intent-filter>
     8 
     9         </receiver>
    10 
    11         <receiver android:name="cn.csc.broadcast.PartyReceiver2">
    12 
    13             <intent-filter >
    14 
    15                 <action android:name="cn.csc.broadcast.PARTY"/>
    16 
    17             </intent-filter>
    18 
    19         </receiver>
    20 
    21         <receiver android:name="cn.csc.broadcast.PartyReceiver3">
    22 
    23             <intent-filter >
    24 
    25                 <action android:name="cn.csc.broadcast.PARTY"/>
    26 
    27             </intent-filter>
    28 
    29         </receiver>

    4)运行结果:

     

    多点几次按钮,顺序仍然一样。这里没有设置优先级,就按清单文件中的顺序一个个向下传递。

    5)修改清单文件,添加优先级:

     1 <receiver android:name="cn.csc.broadcast.PartyReceiver1">
     2 
     3             <intent-filter android:priority="0">
     4 
     5                 <action android:name="cn.csc.broadcast.PARTY"/>
     6 
     7             </intent-filter>
     8 
     9         </receiver>
    10 
    11         <receiver android:name="cn.csc.broadcast.PartyReceiver2">
    12 
    13             <intent-filter android:priority="500">
    14 
    15                 <action android:name="cn.csc.broadcast.PARTY"/>
    16 
    17             </intent-filter>
    18 
    19         </receiver>
    20 
    21         <receiver android:name="cn.csc.broadcast.PartyReceiver3">
    22 
    23             <intent-filter android:priority="1000">
    24 
    25                 <action android:name="cn.csc.broadcast.PARTY"/>
    26 
    27             </intent-filter>
    28 
    29         </receiver>

    6)重新运行:

     

    优先级数字越大,优先级就越高。

    若优先级全设置为500:

    可见,优先级相同则按注册顺序依次传递。

    7)设置不同的优先级,然后在高优先级Receiver中修改消息内容:

    Receiver1:

    1 Log.i("PARTY","F1:"+getResultData());
    2 
    3 setResultData("明天早上5点校西门集合,一起去春熙路看美女");

    Receiver2:

    1 Log.i("PARTY","F2:"+getResultData());
    2 
    3 setResultData("明天自由活动");

    Receiver3:

    Log.i("PARTY","F3:"+getResultData());

    8)运行结果:

     

    9)高优先级截断广播消息:

    Receiver1:

    1 Log.i("PARTY","F1:"+getResultData());
    2 
    3 setResultData("明天早上5点校西门集合,一起去春熙路看美女");
    4 
    5 abortBroadcast();

    运行结果:

     

    10)设置sendOrderedBroadcast()方法的resultReceiver参数:

    sendOrderedBroadcast(intent, null, new PartyReceiver3(), null, 0, "明天下午16点校南门集合,一起去龙湖看电影,聚餐", null);

    Receiver1中任然截获广播消息:

    1 Log.i("PARTY","F1:"+getResultData());
    2 
    3 setResultData("明天早上5点校西门集合,一起去春熙路看美女");
    4 
    5 abortBroadcast();

    运行结果:

     

    可见,resultReceiver指定的接收者,即使高优先级接收者截获广播消息,它也一定能收到广播消息。

    以上,就是学到的Android中关于广播接收者的内容。

    补充:本地广播的简单使用,参考《第一行代码》

    1)修改Activity代码:

     1 public class MainActivity extends ActionBarActivity {
     2 
     3       private LocalBroadcastManager manager;
     4 
     5       private LocalReceiver localReceiver;
     6 
     7     @Override
     8 
     9     protected void onCreate(Bundle savedInstanceState) {
    10 
    11         super.onCreate(savedInstanceState);
    12 
    13         setContentView(R.layout.activity_main);
    14 
    15         Button btn = (Button) findViewById(R.id.btn_send_normal);
    16 
    17         manager = LocalBroadcastManager.getInstance(this);
    18 
    19         btn.setOnClickListener(new OnClickListener() {
    20 
    21                  @Override
    22 
    23                  public void onClick(View v) {
    24 
    25                       // TODO Auto-generated method stub
    26 
    27                       Intent intent = new Intent("cn.csc.broadcast.PARTY");
    28 
    29                       intent.putExtra("content", "明天下午16点校南门集合,一起去龙湖看电影,聚餐");
    30 
    31                       manager.sendBroadcast(intent);
    32 
    33                  }
    34 
    35           
    36 
    37         });
    38 
    39         IntentFilter filter = new IntentFilter();
    40 
    41         filter.addAction("cn.csc.broadcast.PARTY");
    42 
    43         localReceiver = new LocalReceiver();
    44 
    45         manager.registerReceiver(localReceiver, filter);
    46 
    47     }
    48 
    49  
    50 
    51       @Override
    52 
    53       protected void onDestroy() {
    54 
    55            // TODO Auto-generated method stub
    56 
    57            manager.unregisterReceiver(localReceiver);
    58 
    59       }
    60 
    61 }

    主要就是之前有Context调用sendBroadcast()改为由LocalBroadcastManager调用,及注册接收者。

    2)新建一个接收本地广播的接收者:

     1 public class LocalReceiver extends BroadcastReceiver {
     2 
     3  
     4 
     5       @Override
     6 
     7       public void onReceive(Context context, Intent intent) {
     8 
     9            // TODO Auto-generated method stub
    10 
    11            Toast.makeText(context, intent.getStringExtra("content"), Toast.LENGTH_LONG).show();
    12 
    13       }
    14 
    15 }

    这样,这个广播就只能在本应用中可见,该应用之外不可见了。

    注意一点,本地广播中这种广播接收者注册方式称之为动态注册,而前面的全局广播接收者注册是在清单文件中注册的,称之为静态注册,前面的广播接收者的注册也都可以使用动态注册,在此就不一一测试了。静态注册的好处是即使不启动应用,也能够接收广播消息进行需要的简单处理。而本地广播是当前应用发出的只在本应用内部可见的广播消息,所以只能采用动态注册,而且完全没必要采用静态注册,能发出广播消息就说明该应用已然处于启动的状态了。

  • 相关阅读:
    Spring Boot 自定义 Banner 教程
    Spring Boot 操作 Excel
    Spring Boot 文件上传简易教程
    SpringMVC 处理请求的整个流程?入口?
    实现单例模式的9个方法
    Mybatis Generator最完整配置详解
    接口限流
    添加jar包到本地Maven仓库
    Java ConcurrentModificationException异常原因和解决方法
    RESTful API 设计指南[转]
  • 原文地址:https://www.cnblogs.com/dqrcsc/p/4649313.html
Copyright © 2011-2022 走看看