微子学Android之BroadcastRecevier

在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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值