四大组件之一:BroadcastReceiver

来源:互联网 发布:投稿系统 php 编辑:程序博客网 时间:2024/06/11 08:17

BroadcastReceiver:广播接收器
一:BroadcastReceiver的简述
BroadcastReceiver也是Android系统的四大组件之一,这种组件本质上就是一种全局的监听器。用于监听系统全局的广播消息。之前在按钮上添加的监听器只是程序级别的监听器。
由于BroadcastReceiver是一种全局的监听器,因此它可以非常方便地实现系统中不同组件之间的通信。
例如客户端程序用startService()方法启动的Service之间的通信,就可以借助于BroadcastReceiver来实现。一种系统级别的消息传递机制,可以作用在整个系统中,当系统接受到与之匹配的广播时,会自动启动Receiver来处理广播.它没有生命周期,本质上只是一个系统级别的监听器—-它专门负责监听各程序所发出的Broadcast.

二:BroadcastReceiver创建过程
1)创建Receiver
编写类继承BroadcastReceiver,重写其OnReceiver方法。
如果OnReceiver方法不能在10秒内执行完成,android会认为该程序无响应,所以不要在该方法执行一些耗时的操作。否则弹出ANR(Application No Response)的对话框。如果需要完成一些耗时的操作,则可以考虑通过Intent启动一个Service完成。不要使用新线程完成。因为广播接收器的生命周期很短。可能出现子线程还没有结束,广播解释器已经退出了。
2)注册Receiver有两种方式(静态注册和动态注册)
(a)在配置文件中添加标签
为其制定android:name属性与 intent-filter的action
(b)调用context的registerReceiver方法,参数为Receiver对象与InterFilter对象
在onDestory方法取消注册,否则出现异常:unregisterReceiver(receiver);

3)发送广播:
(a)调用sendBroadcast(Intent)默认的广播机制,所有能与Intent的Action匹配的Receiver都会被触发,理论上所有Receiver同时去接受广播,消息传递的效率高
缺点:接收者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent的传播
(b)有序广播sendOrderBoradcast(Intent,String)广播是根据Receiver的优先级依次接收Broadcast.
如A>B>C的优先级:Broadcast先传给A,再传给B,最后给C。
优先级通过中的android:priority,越大优先级别越高,取值范围-1000到1000,也可以调用IntentFilter对象的setPriority()进行设置。
在传递过程中,可以加入额外数据传递给下一个接收器
setResultExtras(Bundle)传递数据
也可以终止广播的传递,后面的接收者就无法接受到广播
abortBradcast()终止广播
(c)粘性广播sendStickyBroadcast()上面两种广播是及时广播,而粘性广播可以保留广播的信息。如果发广播的时候,没有接收器接受。等到有接收器的会再一次发送该广播。需要权限android.permission.BROADCAST_STICKY。

4)使用系统广播
android.intent.action.TIME_SET:系统时间被修改。
android.intent.action.DATE_CHANGED:系统日期被修改。
android.intent.action.BOOT_COMPLETED:系统启动完成。
android.intent.action.BATTERY_CHANGED:设备电量改变。
android.intent.action.BATTERY_LOW:设备电量低。
android.intent.action.ACTION_POWER_CONNECTED:设备连接电源。
android.intent.action.ACTION_POWER_DISCONNECTED:设备断开电源。
android.provider.Telephony.SMS_RECEIVED:系统收到短信。
android.intent.action.NEW_OUTGOING_CALL:拨打电话。
android.intent.action.SCREEN_OFF当屏幕锁屏的时候触发
android.intent.action.SCREEN_ON屏幕解锁的时候触发
android.intent.action.USER_PRESENT当用户重新唤醒手持设备时触发

ACTION_TIME_CHANGED:系统时间被改变
ACTION_TIMEZONE_CHANGED:系统时区被改变
ACTION_BOOT_COMPLETED:系统启动完成
ACTION_PACKAGE_ADDED:系统添加包
ACTION_PACKAGE_CHANGED:系统的包改变
ACTION_PACKAGE_REMOVED:此外的包被删除
ACTION_PACKAGE_RESTARTED:系统的包被重启
ACTION_PACKAGE_DATA_CLEARED:系统的包数据被清空
ACTION_SHUTDOWN:系统被关闭

例子:1.获取短信的内容,做一个短信接收器
2.IP拨号:前面加上”17951”
如果触发拨打电话的Action,则会发布一个
“android.intent.action.NEW_OUTGOING_CALL”
的Broadcast出来,只需要针对它进行拦截即可,
获取数据,然后在加上IP前缀,把处理过的号码添加到数据传递给下一个Receiver。
处理接收拨打电话的Broadcast,需要对Android增加权限:
“android.permission.PROCESS_OUTGOING_CALLS
3.接收断开和连接电源的广播
发出打电话的广播(点击打电话的按钮)——认为的加一个广播接收器(1000),10086,17951+10086———》自带的广播接收器(跳转到拨打电话的界面)
Android系统中内置了非常多的Broadcast,用于对系统事件的响应、拦截、操作,
在实际开发中,可以根据需要,查找Android源代码中相应的应用中的代码找到需要的
Broadcast,以及如何处理的例子。

package com.xspacing.broadcastreceiver;import android.app.Activity;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {    private SecondReceiver mSecondReceiver;    private ThirdReceiver thirdReceiver;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        registorBrodcast();    }    /**     * 动态注册广播     */    private void registorBrodcast() {        mSecondReceiver = new SecondReceiver();        IntentFilter filter = new IntentFilter();        filter.setPriority(10000);        filter.addAction("com.xspacing.broadcastreceiver.action");        registerReceiver(mSecondReceiver, filter);    }    /**     * 发送无序广播     *      * @param v     */    public void sendBroadcastReceiver(View v) {        Intent intent = new Intent();        intent.putExtra("key", "嘻嘻,广播来了");        intent.setAction("com.xspacing.broadcastreceiver.action");        sendBroadcast(intent);    }    /**     * 发送有序广播     *      * @param v     */    public void sendOrderBroadcastReceiver(View v) {        Intent intent = new Intent();        intent.putExtra("key", "嘻嘻,有序广播来了");        intent.setAction("com.xspacing.broadcastreceiver.action");        sendOrderedBroadcast(intent, null);    }    /**     * 发送粘性广播     */    public void sendStickyBroadcastReceiver(View v) {        Intent intent = new Intent();        intent.setAction("com.xspacing.stickybroadcastreceiver.action");        sendStickyBroadcast(intent);        // 特殊,可以后动态注册广播        IntentFilter filter = new IntentFilter();        filter.addAction("com.xspacing.stickybroadcastreceiver.action");        thirdReceiver = new ThirdReceiver();        registerReceiver(thirdReceiver, filter);    }    @Override    protected void onDestroy() {        // 取消动态注册广播        unregisterReceiver(mSecondReceiver);        unregisterReceiver(thirdReceiver);        super.onDestroy();    }}
package com.xspacing.broadcastreceiver;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.widget.Toast;/** *  * @ClassName FirstReceiver.java * @Description 无序广播接收器 * @author smile * @version v1.0 * @date 2016年10月10日 */public class FirstReceiver extends BroadcastReceiver {    // 收到匹配广播,所执行的逻辑代码都是在这里实现    // 它的生命周期很短,不能执行耗时操作,也不能在此开启新线程,可以开启服务,在服务里面开启线程    @Override    public void onReceive(Context context, Intent intent) {        String value = intent.getStringExtra("key");        Bundle bundle = getResultExtras(true);        String data = bundle.getString("name");        Toast.makeText(context, value + "FirstReceiver" + data, Toast.LENGTH_SHORT).show();    }}
package com.xspacing.broadcastreceiver;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.widget.Toast;public class SecondReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        String value = intent.getStringExtra("key");        Bundle bundle = new Bundle();        bundle.putString("name", "我是额外的数据");        // 向下一个广播传输额外的数据        setResultExtras(bundle);        Toast.makeText(context, value + ",SecondReceiver", Toast.LENGTH_SHORT).show();    }}
package com.xspacing.broadcastreceiver;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.widget.Toast;public class ThirdReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Toast.makeText(context, "收到粘性广播", Toast.LENGTH_SHORT).show();    }}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.xspacing.broadcastreceiver.MainActivity" >    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="sendBroadcastReceiver"        android:text="发送无序广播" />    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="sendOrderBroadcastReceiver"        android:text="发送有序广播" />     <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="sendStickyBroadcastReceiver"        android:text="发送粘性广播" /></LinearLayout>

AndroidManifest.xml

 <uses-permission android:name="android.permission.BROADCAST_STICKY" />
  <!-- priority:广播优先级,只有有序广播有效 -->        <receiver android:name="com.xspacing.broadcastreceiver.FirstReceiver" >            <intent-filter android:priority="100" >                <action android:name="com.xspacing.broadcastreceiver.action" />            </intent-filter>        </receiver>
0 0
原创粉丝点击