BroadcastReceiver:
在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中用<receiver>标签生命注册,并在标签内用<intent- filter>标签设置过滤器。
另一种方式是,动态的在代码中先定义并设置好一个 IntentFilter 对象,然后在需要注册的地方调Context.registerReceiver()方法,如果取消时就调用 Context.unregisterReceiver()方法。如果用动态方式注册的BroadcastReceiver的Context对象被销毁时,BroadcastReceiver也就自动取消注册了。(特别注意,有些可能需要后台监听的,如短信消息)
1.静态注册BroadcastReceiver:
静态注册比动态注册麻烦点,先新建一个类继承BroadcastReceiver,如:
clsReceiver2.java
然后到AndroidManifest.xml 添加receive标签
< intent - filter >
< action
android:name = " com.testBroadcastReceiver.Internal_2 " />
</ intent - filter >
</ receiver >
第一个name是类名,即你的继承BroadcastReceiver的类的名字,里面实现了BroadcastReceive的onReceive()方法,来处理你接到消息的动作。
2.动态注册BroadcastReceiver:
主要代码部分为:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(String); //为BroadcastReceiver指定action,即要监听的消息名字。
registerReceiver(MyBroadcastReceiver,intentFilter); //注册监听
unregisterReceiver(MyBroadcastReceiver); //取消监听
(一般:在onStart中注册,onStop中取消unregisterReceiver)
private class MyBroadcastReceive extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if(intent.ACTION_BATTERY_CHANGED.equals(action)) //判断是否接到电池变换消息
{
//处理内容
}
}
}
========================================================================
Broadcast:
发送广播消息,把要发送的信息和用于过滤的信息(如Action、Category)装入一个Intent对象,然后通过调用 Context.sendBroadcast()、sendOrderBroadcast()或sendStickyBroadcast()方法,把 Intent对象以广播方式发送出去。
例如:
intent.putExtra( " Name " , " hellogv " );
intent.putExtra( " Blog " , " http://blog.youkuaiyun.com/hellogv " );
sendBroadcast(intent); // 传递过去
BroadcastReceiver,作为一个广播接收者,因为android组件之间消息的传递基于intent,所以广播接收者想要接收什么类型的广播,将receiver标签下的intent-filter标签下的action标签的值置为那个广播类型即可,如
- <receiver android:name=".IncomingSMSReceiver">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED"/>
- <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
- </intent-filter>
- </receiver>
上面这段代码其实就注册了两个广播接收的类型,系统开机启动完成时的广播和短信到来的广播(注意加上短信接受权限)都会被接收到,然后可以再onReceive()方法里面写上你想写的代码了。
额外提个事,权限问题一定要加上,现在的logcat里面Permission denied的提示都不是红色的了,改成橙色的,我还以为我这没出问题,找了半天代码的问题,结果后来还是发现权限配错了,本来想拦截拨出的电话的,结果没配权限怎么都拿不到数据啊,找了十几分钟。虽然相对前些天我找一个上午的权限问题进步多了,但是我还是这么认为,玩android权限问题都要找个十来分钟的话那就太2了。
除了在清单文件中配置以外,也可以在代码中订阅
- IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
- Receiver receiver = new Receiver();
- registerReceiver(receiver, filter);
Receiver是你自己写的继承自BroadcastReceiver的类。IntentFilter就对应着Action啦。
还有一个细节是sendBroadcast的三种发送方法。
sendBroadcast(),sendOrderedBroadcast() 和 sendStickyBroadcast()
sendBroadcast()这个方法的广播是能够发送给所有广播接收者,按照注册的先后顺序,如果你这个时候设置了广播接收者的优先级,优先级如果恰好与注册顺序相同,则不会有任何问题,如果顺序不一样,会出leaked IntentReceiver 这样的异常,并且在前面的广播接收者不能调用abortBroadcast()方法将其终止,如果调用会出BroadcastReceiver trying to return result during a non-ordered broadcast的异常,当然,先接收到广播的receiver可以修改广播数据。
sendOrderedBroadcast()方法顾名思义就是priority的属性能起作用,并且在队列前面的receiver可以随时终止广播的发送。还有这个api能指定final的receiver,这个receiver是最后一个接收广播时间的receiver,并且一定会接收到广播事件,是不能被前面的receiver拦截的。实际做实验的情况是这样的,假设我有3个receiver依序排列,并且sendOrderedBroadcast()方法指定了一个finalReceiver,那么intent传递给这4个Receiver的顺序为Receiver1-->finalReceiver-->Receiver2-->finalReceiver-->Receiver3-->finalReceiver。这个特性可以用来统计系统中能监听某种广播的Receiver的数目。
下面是广播接收者的生命周期以及一些细节部分:
1.广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁
2.广播接收者中不要做一些耗时的工作,否则会弹出Application No Response错误对话框
3.最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉
4.耗时的较长的工作最好放在服务中完成
至于广播接收者接收用户的短信,实现ip拨号等功能,明白上面的话实现起来就轻而易举了。