Android 系列笔记 七 - 广播

获取打电话的广播

1.在清单文件中配置receiver,指定要接收广播的类型,并添加相应的权限。

1
2
3
4
5
<receiver android:name = "包名+类名">
<intent-filter>
<action android:name = "android.intent.action.NEW_OUTGOING_CALL"/>//外拨电话
</intent-filter>
</receiver>

2.创建一个类继承自BrocastReceiver 并重写onReceive()方法,该方法在接收到广播的时候调用

1
2
3
4
//在打电话广播中,会携带拨打电话的号码
String phoneNumber = getResultData();//获取数据
//把新的号码放到广播中
setResultData(phoneNumber);

即便广播接收者所在进程已经被关闭,当系统发送出的action跟该广播的action是匹配的,系统会启动该广播接收者所在的进程,并把广播发送给该广播接收者

监听短信

1.在清单文件中配置广播,并添加相应权限

1
2
3
4
5
<receiver android:name = "包名+类名">
<intent-filter>
<action android:name = "android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>

2.创建一个类继承自BrocastReceiver 并重写onReceive()方法,该方法在接收到广播的时候调用

1
2
3
4
5
6
7
Object[] objs=intent.getExtras().get("pdus");//获得一组短信
for(Object obj:objs){
//得到短信对象
SmsMessage smsMessage=SmsMessage.createFromPdu((byte[])obj);
String body=smsMessage.getMessageBody();
String sender=smsMessage.getOriginatingAddress();
}

4.0之后,广播接收者所在进程如果从来没启动过,那么广播接收者不会生效
4.0之后,如果系统自动关闭广播接收者所在进程,在广播中的action跟该广播接收者的action匹配时,系统会启动该广播接收者所在的进程,但是如果是用户手动关闭该进程,那么该进程会进入冻结状态,再也不会启动,直到下一次用户手动启动该进程。

监控SD卡状态

1.在清单文件中配置广播,并添加相应权限

1
2
3
4
5
6
7
8
<receiver android:name = "包名+类名">
<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>

2.onReceive()

1
2
3
4
5
//判断收到的是什么广播
String action = intent.getAction();
if(action.equals("android.intent.action.MEDIA_MOUNTED")){
Toast.makeText(context, "SD卡可用", Toast.LENGTH_SHORT).show();
}

开机启动应用

1.在清单文件中配置广播,并添加相应权限

1
2
3
4
5
<receiver android:name = "包名+类名">
<intent-filter>
<action android:name = "android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

2.onReceive()

1
2
3
4
Intent it = new Intent(context, MainActivity.class);
//创建任务栈,存放启动的activity
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(it);

监控应用状态: 安装、更新、卸载

1.在清单文件中配置广播,并添加相应权限

1
2
3
4
5
6
7
8
<receiver android:name = "包名+类名">
<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>

2.onReceive()

1
2
3
4
5
6
//判断收到的是什么广播
String action = intent.getAction();
if(action.equals("android.intent.action.PACKAGE_ADDED")){
Uri uri = intent.getData();
Toast.makeText(context, uri.toString() + " 应用安装了", Toast.LENGTH_SHORT).show();
}

自定义广播

发送自定义广播

一般都是隐式意图

1
2
3
4
5
Intent intent = new Intent();
//自定义
intent.setAction("包名.动作");
intent.putExtras("","");
sendBroadcast(intent);

接收自定义广播

清单文件中配置广播接收者

1
2
3
4
5
<receiver android:name = "包名+类名">
<intent-filter>
<action android:name = "包名.动作"/>
</intent-filter>
</receiver>

发送无序广播

没有顺序的广播,所有与广播中的action匹配的广播接收者都可以收到这条广播,并且是没有先后的顺序,视为同时收到
sendBroadcast(intent);//无序广播

发送有序广播

有顺序的广播,所有与广播中的action匹配的广播接收者都可以收到这条广播,但是是有先后的顺序,按照广播接收者的优先级排序
有序广播可以被拦截,可被终止,可以被修改数据

1
2
3
4
5
6
7
8
9
10
Intent intent = new Intent();
intent.setAction("it.java.fdm");
sendOrderedBroadcast(intent,
null,//第二个参数为接收广播需要的权限
null,//最终的广播接收者,只接收该条广播并且一定可以收到,不需要在清单文件中配置
null,
0,
"每人发100斤大米",
null);//Bundle对象,携带数据
sendBroadcast(intent);

有序广播接收者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<receiver android:name = "包名+类名">
<intent-filter android:priority = "1000">
<action android:name = "it.java.fdm"/>
</intent-filter>
</receiver>
<receiver android:name = "包名+类名">
<intent-filter android:priority = "800">
<action android:name = "it.java.fdm"/>
</intent-filter>
</receiver>
<receiver android:name = "包名+类名">
<intent-filter android:priority = "600">
<action android:name = "it.java.fdm"/>
</intent-filter>
</receiver>

onReceive()中:

1
2
String data = getResultData();//"每人发100斤大米"
setResultData("每人发120斤大米");//修改数据