- 广播的意义其实就是告诉多个APP同一事件,是普通一对一事件的扩展
- 电量改变、收发短信、开机、电话、屏幕解锁等,都是广播
- 广播接收者是四大组件之一。注意不是广播
- 四大组件的都要在清单文件manifest文件中定义,注意和Activity同级
- 注意权限的问题,接收打电话、短信侵犯了隐私
- 广播实际上是先发一条广播,广播接收者先收到广播,可以修改广播数据,最后发给实际生效的Activity
- 广播存活的进程就是部署所在的application,即使该进程被杀死了,当广播发出时,系统会启动这个进程,然后发广播给该进程。 这种监测者的实现方式是为了给系统节省资源,没必要一直开着这种监测进程
- 如果广播接收者进程是用户手动关闭(app info下的FORCE STOP,见下图),那就不会再次启动,4.0之后的特性
- 广播实际上也是通过Intent发送的
- 广播接收者进程如果从来没有启动过,4.0以后就不会生效
电话短信接收者
<application>
<activity>
</activity>
<receiver android:name="packageName.ClassName">
<intent-filter>
<action ---- 指定接收什么类型的广播,这里值是表示往外打电话的广播
android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
<receiver android:name="packageName.ClassName">
<intent-filter android:priority="1000"> -- 定义优先级,优先级[-1000,1000]
<action ---- 接收收短信的广播,这个不提示,操蛋
android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
// 电话接收者
public class CallReceiver extends BroadcastReceiver{
public void onReceive(Context c, Intent intent){
// 会带过来拨打的电话号码
String number = getResultData();
//广播接收者不是Context子类,因此把Context传进来
String str1 = context.getSharedPreferences("ip", Context.MODE_PRIVATE).getString("str1");
number = str1+number;
setResultData(number); //将数据设置给广播
}
}
// 短信接收者
public class SmsReceiver extends BroadcastReceiver{
public void onReceiver(Context context Intent intent){
Bundle bundle = intent.getExtras();
//短信的抽象叫做pdus, pdu是协议数据单元,每个object表示一条短信
Object[] objects = bundle.get("pdus");
for(Object o : objects){//多条短信原因:内容超过运营商规定长度
SmsMessage sms = SmsMessage.createFromPdu((byte[])o);
//sms就是短信的所有东西。。包括地址,短信内容等
if (sms.getOriginatingAddress().equals("39393")){
//短信应用和短信是两回事,收到短信这个事件会发广播,
//短信应用收到广播然后显示出来
abortBroadcast(); //丢弃广播,低优先级接收者就收不到了
}
}
}
}
SD卡状态广播接收
- 广播也是通过Intent传递的,SD卡广播定义的时候就有data,因此需要完全匹配,因此定义了一个data
<!--同一个Receiver接收多个广播的写法-->
<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>
public class SDCardCast extends BroadcastReceiver{
public void onReceive(Context context, Intent){
String str = intent.getAction();
if ("android.intent.action.MEDIA_MOUNTED".equals(str)){
}else if(){
//业务逻辑.......
}
}
}
开机广播接收者
// BOOT_COMPLETED是广播Action的名字
public class BootReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent){
Intent it = new Intent(context, XXX.class);
//在context外部启动Activity必须设置这个flag,实际就是创建一个新的Activity栈
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(it);
}
}
应用状态广播
- 应用状态有三种:安装、更新、卸载
// PACKAGE_ADDED\PAGEAGE_REMOVED\PACKAGE_REPLACED
//intent-fliter还要定义一个data android:scheme="package"
public class AppStatusReceiver extends BroadcastReceiver{
public void onReceive(Context c, Intent it){
String action = it.getAction();
Uri uri = it.getData();
if (action.equals("PACKAGE_ADDED")){
System.out.println(uri.toString());
}else if(){
/*
其他逻辑.....
*/
}
}
}
- 总结下:
- 定义类继承BroadcastReceiver
- manifest中定义Receiver,并通过intent-filter中的action定义接收广播类型
- 权限添加