微子学Android之BroadcastRecevier

来源:互联网 发布:汕头网页美工培训 编辑:程序博客网 时间:2024/06/04 19:11

在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中用标签生命注册,并在标签内用标签设置过滤器。

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

另外,若在使用sendBroadcast()的方法是指定了接收权限,则只有在AndroidManifest.xml中用标签声明了拥有此权限的BroascastReceiver才会有可能接收到发送来的Broadcast。同样,若在注册BroadcastReceiver时指定了可接收的Broadcast的权限,则只有在包内的AndroidManifest.xml中 用标签声明了,拥有此权限的Context对象所发送的Broadcast才能被这个 BroadcastReceiver所接收。

  1. 静态注册
    静态广播首先需要在AndroidManifest.xml中注册广播
  <receiver android:name=".BroadCastnormalStatic">            <intent-filter>               <!--广播的名称-->                <action android:name="android.1111" />            </intent-filter>  </receiver>

然后在程序中发送广播

   private void sendnormalstatic() {        btn1 = (Button) findViewById(R.id.btn1);        btn1.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {            //在Intent中添加广播名称,通过sendBroadcast()方法将广播发送出去                Intent intent = new Intent("android.1111");                sendBroadcast(intent);            }        });    }

再新建广播接收器,接收此广播

public class BroadCastnormalStatic extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {         Log.i("TAG","普通静态广播");    }}

2.普通动态注册
动态注册就是在不需要再AndroidManifest.xml中注册,直接在代码中注册。
建议在onStart()中进行注册:

 @Override    protected void onStart() {        super.onStart();        broadCastnormal = new BroadCastnormal();        IntentFilter intentFilter = new IntentFilter();        intentFilter.addAction("android.2222");        registerReceiver(broadCastnormal, intentFilter);    }

记得在onStop()中注销:

  @Override    protected void onStop() {        super.onStop();        unregisterReceiver(broadCastnormal);    }

在代码中进行发送:

  private void sendnormal() {        btn2 = (Button) findViewById(R.id.btn2);        btn2.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent("android.2222");                sendBroadcast(intent);            }        });    }

再注册广播接收器进行接收广播:

public class BroadCastnormal extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Log.i("TAG","普通动态广播");    }}

有序广播
发送有序广播的方法时:sendOrderedBroadcast();
假设有3个广播接收者可以同时接收一个广播,如果这个广播使用sendOrderBroadcast()发送有序广播,那么这三个广播接受者,谁的优先级高谁先接收。优先级高的广播可以将广播中断,这样优先级低的广播就接收不到了。
设置优先级在广播注册中的<intent-filter> 中使用
android:priority属性。这个属性的范围是-1000到1000,数值越大,优先级越高。
在广播接收器中可以使用setResultExtras方法,将一个Bundle对象设置为结果集对象,传递到下一个接受者那里,这样优先级低的接收者可以用getRusultExtras方法获取最新经过处理的信息集合。
使用sendOrderedBroadcast方法发送有序广播时,需要一个权限参数,如果为null表示不要求接受者声明指定的权限,如果不为null,则表示接受者如果接收此广播,需要声明指定权限。这样做是从安全角度考虑的。系统的短信是有序广播的,假如一个应用有拦截短信的功能,当短信来临时它优先接收短信广播,必要时拦截该广播,这样的应用必须声明权限。
终止广播的方法是abortBroadcast()。
同级别的接收先是随机的,再发送到低优先级的,假如同级别的把广播拦截,出同级别的外不能接收到广播。
动态注册的广播中,收到广播的顺序是:注明优先级的,代码注册的,没有优先级的;若都没有优先级,代码注册的优先。

粘性广播
粘性广播在发送消息后一直存在系统的消息列表中,等待对应的处理器去处理。如果没有处理器处理,这个消息就一直在消息列表中等待。粘性广播中如果处理器被销毁,那么下次重建时就会自动接收到数据。
发送粘性广播: sendStickyBroadcast(intent);
发送粘性广播需要权限:<uses-permission android:name = "android.permisson.BROADCAST_STICKY">
取消粘性广播:removeStickyBroadcast()intent);

常用的系统广播
1.开机启动
当我们的系统应用需要实现开机启动功能时,我们可以订阅系统的“启动完成”这个广播。接收到这个广播我们就能开启自己的服务了。
实现方法:
首先我们需要声明接收开机启动广播的权限。

<uses-permisson android:name="android:permisson.RECEIVE_BOOT_COMPLETED"/>

然后在注册广播时

<intent-filter>  <action android:name="android.intent.action.BOOT_COMPLETED"/>  <category android:name ="android.intent.category.DEFAULT"/></intet-filter>

2.监听网络变化
假如用户在浏览我们的应用时,突然网络断开,我们就需要提醒用户网络已断开。要实现这个功能,我们可以接收网路变化的广播,当网络由连接变为断开时,系统就会发送一条广播,我们接收到后,再通过网络的状态做出相应的操作。
实现:
首先声明权限:

<uses-permisson android:name = android.permission.ACCESS_NETWORK_STATE>

然后在声明广播时

<intent-filter>  <action android:name="android.intent.action.CONNECTIVITY_CHANGE"/>  <category android:name ="android.intent.category.DEFAULT"/></intet-filter>

3.电量变化
如果我们使用阅读软件,也可能是全屏阅读,这时候用户就看不到电量变化,我们就可以为他提供电量变化信息。要做到这点,我们需要先获取到电量变化的广播,再计算百分比信息。
首先注册广播:

<intent-filter>  <action android:name="android.intent.action.BATTERY_CHANGED"/>  <category android:name ="android.intent.category.DEFAULT"/></intet-filter>

在广播接收器中,我们可以这些处理:

int currLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL,0);//当前电量int total = intent.getIntExtra(BatteryManager.EXTRA_SCALE,1);//总电量int percent = currLevel*100/total;

如果我们要立即获取电量,而不是等电量变化的广播,我们可以这样:

Intent batteryIntent = getApplicationContext().registerReceiver(null,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));int currLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL,0);//当前电量int total = intent.getIntExtra(BatteryManager.EXTRA_SCALE,1);//总电量int percent = currLevel*100/total;

4.收发短信
使用Android API类库可以自己实现收发短信的功能:
信息的发送,对mms应用程序来讲就是在信息数据库中创建并维护一条信息记录,真正的发送过程是交由底层(Frameworks层)函数来实现。
核心代码:

(1)SmsManager manager = SMSManager.getDefault();//获取默认的消息管理器(2)ArrayList<String> list = manager.divideMessage(String txt);//拆分长短信(3)manager.sendTextMessage(String phone,null,String content,null,null);//发送短信

发送短信的权限

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

5.接收短信
系统在收到短信后会发出一个有序广播,我们可以从收到的广播的Intent中获得短信消息。
实现:
首先我们先设置好权限

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

注册广播的action为

android.provider.Telephony.SMS_RECEIVED

代码:

这里写代码片
0 0
原创粉丝点击