生命周期:
生命周期只有十秒左右,如果在onReceive()内做超过十秒内的事情,就会报错。
每次广播到来时,会重新创建BroadcastReceiver对象,并且调用onReceive()方法,执行完以后,该对象即被销毁.当onReceive()方法在10秒内没有执行完毕,Android会认为该程序无响应.所以在
BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR广播的分类:
A.无序广播:所有与广播中的action匹配的广播接收者都可以接收到这条广播,但是并没有先后的顺序,视为同时收到(发送一个广播,所以监听该广播的广播接收者都可以监听到改广播。)
B.有序广播:所有与广播中的action匹配的广播接收者都可以收到这条广播,但是是先后顺序,按照广播接收者的优先级排序
sendOrderedBroadcast(intent,receiverPermission);
sendOrderedBroadcast(intent,receiverPermission, resultReceiver,
scheduler, initialCode, initialData, initialExtras)
意图,广播,所有匹配的这一意图将接收机接收广播。
receiverPermission这是权限,一个接收器必须持以接收您的广播。如果为null,不经许可的要求。
resultReceiver您自己BroadcastReceiver来当作最后的广播接收器。
调度自定义处理程序,用以安排resultReceiver回调;如果为null将语境中的主线程举行。
initialCode一种结果代码的初始值。通常为Activity.RESULT_OK。这个值是-1;为其他int型 也可以,如0,1,2;
initialData一种结果数据的初始值。通常情况下为空,是String类型;
initialExtras一种结果额外的初始值。通常情况下为空,是Bundle;
拓展:
1, 该广播的级别有级别之分,级别数值是在-1000到1000之间,值越大,优先级越高;
2, 同级别接收是先后是随机的,再到级别低的收到广播;
3, 同级别接收是先后是随机的,如果先接收到的把广播截断了,同级别的例外的接收者是无法收到该广播的。(abortBroadcast())
4,能截断广播的继续传播,高级别的广播收到该广播后,可以决定把该钟广播是否截断掉。
5,实验现象,在这个方法发来的广播中,代码注册方式中,收到广播先后次序为:注明优先级的、代码注册的、没有优先级的;如果都没有优先级,代码注册收到为最先。
C.异步广播, 当处理完之后的Intent,依然存在,这时候registerReceiver(BroadcastReceiver,IntentFilter)还能收到他的值,直到你把它去掉,不能将处理结果传给下一个接收者,无法终止广播.
sendStickyBroadcast(intent);
当处理完之后的Intent,依然存在,直到你把它去掉。
发这个广播需要权限<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
去掉是用这个方法removeStickyBroadcast(intent);但别忘了在执行这个方法的应用里面AndroidManifest.xml同样要加上面的权限;
sendStickyOrderedBroadcast(intent,resultReceiver, scheduler,
initialCode, initialData,initialExtras)
这个方法具有有序广播的特性也有异步广播的特性
发送这个广播要:<uses-permissionandroid:name="android.permission.BROADCAST_STICKY" />这个权限。才能使用这个方法。如果您并不拥有该权限,将抛出SecurityException的。
代码中注册广播:
(三)
代码中注册广播
注册广播方法一:registerReceiver(BroadcastReceiverreceiver, IntentFilter filter),第一个参数是我们要处理广播的BroadcastReceiver(广播接收者,可以是系统的,也可以是自定义的);第二个参数是意图过滤器。
注册广播方法二:registerReceiver(receiver, filter, broadcastPermission, scheduler),第一个参数是BroadcastReceiver(广播接收者,可以是系统的,也可以是自定义的);第二个参数是意图过滤器;第三个参数是广播权限;第四个参数是Hander;
注意:权限重复现象,如果功能清单文件里注册了权限,在该方法再注册,则receiver无法收到广播,如果功能清单文件里没有注册了权限,该方法注册也无法收到。当该方法没有注册权限,功能清单里注册的时候,receiver能收到广播。
总结:在Activity中代码注册广播建议在:onResume()中注册
代码中注销广播
/unregisterReceiver(mBatteryInfoReceiver);
在Activity中代码注销广播建议在:onPuase() 中注销;
不要这这里面注销Activity.onSaveInstanceState(),因为这个方法是保存Intent状态的。
广播的注意事项:
1.凡是广播必须是要到AndroidMainfest中配置信息的
<receiver android:name=".CallReceive"> -->类的全路径
<intent-filter >
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/> -->设置的是接收什么样的广播,根据实现的功能而定
</intent-filter>
</receiver>
实例:
ip拨号器(实现拨打电话的前面加上特定的ip)
<span style="font-size:12px;">/**
* 1.定义java类,继承BoardcastReceiver
* 2.在清单文件中配置reveiver节点(指定name,全类名)
* 3.在intent-filter的节点中,指定action子节点,action的值必须要和接收广播的action的值匹配
* @author abc
*
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 思路:1.将EditText的字符提取出来
* 2.创建一个SharedPreferences的存储对象
* 3.将字符串存储进去(存储的顺序是先获得edit(),然后putstring)
* 4.编辑,提交
* @param v
*/
public void click(View v){
EditText dt = (EditText) findViewById(R.id.ed);
SharedPreferences sp=getSharedPreferences("ip", MODE_PRIVATE);
Editor ed=sp.edit();
ed.putString("ipNumbe",dt.getText().toString());//键值对的形式,前面是键后面是值
}
}
public class CallReceive extends BroadcastReceiver{
/**
* 思路:
* 1.获得原来的打电话的号码
* 2.通过上下文的getSharedPreference获得之前保存的数据,即文本框传进来的数据)
* 3.将看原来的电话加上我们想给他预订的ip
* 4.将电话重新返回给广播
*/
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("call...");
String phone=getResultData();
SharedPreferences sp=context.getSharedPreferences("ip",context.MODE_PRIVATE );
String ipNumber=sp.getString("ipNumber", "");
phone=phone+ipNumber;
setResultData("phone");
abortBroadcast();
}
}
同样要在AndroidMainfest配置信息(在系统默认的</activity>之后)
</span><span style="font-size:12px;"> <receiver android:name=".CallReceive">
<intent-filter >
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
</span>
短信防火墙(实现短信的拦截)
<span style="font-size:12px;">public class SmsReceiver extends BroadcastReceiver {
/**
* 思路:
* 1.拿到短信,封装在intent里面
* 2.把intent放在Bundle里面
* 2.以pdus为键,取出短信的内容,保存到Object[]里
* 3.把object转成byte数组
* 注:联想系统存储短信的思路:
* 1.把短信转成字节数组
* 2.把字节数组存到Object[]数组里面
*3.以"pdus"为key,把object[]数组储存到Bundle里面,在把Bundle 存储到Intent里面
*
*小结:
*1.AndroidMainfest需要配置的信息receiver android:name=".SmsReceiver">
<intent-filter android:priority="1000" >
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
* 2.加权限:<uses-permission android:name="android.permission.RECEIVE_SMS"/>
*/
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object[] obj = (Object[]) bundle.get("pdus");
for (Object object : obj)
{
SmsMessage sms=SmsMessage.createFromPdu((byte[]) object);
if(sms.getOriginatingAddress().equals("1111")){
abortBroadcast();
}
System.out.println(sms.getMessageBody());
}
}
}
其他的程序:一个系统创建的MainActivity,AndroidMainfest中的配置
</span>
监听sd卡的状态(可正常使用,被卸载,,不能使用)
<span style="font-size:12px;">/**
* 小结:
* 1.虚拟机4.0以上的没有sd
* 2.AndrodMainfest中配置
* <receiver android:name=".SDStatusReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.MEDIA_REMOVED" />
<action android:name="android.intent.action.MEDIA_UNMOUNTED" />
<data android:scheme="file"/>
</intent-filter>
</receiver>
其他一眼明了
* @author abc
*
*/
public class SDStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
if("android.intent.action.MEDIA_MOUNTED".equals(action)){
Toast.makeText(context, "SD可用", 0).show();
}
if("android.intent.action.MEDIA_REMOVED".equals(action)){
Toast.makeText(context, "SD被卸载", 0).show();
}
if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){
Toast.makeText(context, "SD不可用", 0).show();
}
}
}
</span>
监控应用的状态(安装,卸载,更新)
<span style="font-size:12px;">public class AppStatusReceiver extends BroadcastReceiver {
/**
* 在AndroidMainfest中添加:
* <receiver android:name=".AppStatusReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
其他的一眼明了
*/
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
Uri uri=intent.getData();
if("android.intent.action.PACKAGE_ADDED".equals(action)){
Toast.makeText(context, uri.toString()+"被安装了", 0).show();
}
if("android.intent.action.PACKAGE_REPLACED".equals(action)){
Toast.makeText(context, uri.toString()+"被更新了", 0).show();
}
if("android.intent.action.PACKAGE_REMOVED".equals(action)){
Toast.makeText(context, uri.toString()+"被卸载了", 0).show();
}
}
}</span>
自定义广播的方法(用的少)
<span style="font-size:12px;">public class MainActivity extends Activity {
/**
* 自定义广播:
* 在发送的广播里面设置intent.setAction("aweiyo");//字符串是自己定义的
* 在接受的广播里里面将AndroidMainfest添加:
* <receiver android:name=".ReceiveBroad">
<intent-filter >
<action android:name="aweiyo"/>//这个就是之前自己设定的
</intent-filter>
</receiver>
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View v){
Intent intent=new Intent();
intent.setAction("aweiyo");
sendBroadcast(intent);
}
}
注:另外一个接收广播的只要在配置文件中添加如上的节点文件,然后新建的类继承BroadcastReceiver即可
</span>
注:原文部分引自(http://yangguangfu.iteye.com/blog/1063732)
(完)