首页 > 代码库 > 广播接收者(Broadcast Receiver)
广播接收者(Broadcast Receiver)
独立寒秋,湘江北去,橘子洲头。 —–毛泽东《沁园春·长沙》
- 广播
- 广播类型
- 有序广播
- 无序广播
- 特殊的广播接收者
- 注册广播接收者的两种方式
- 广播类型
- 系统广播示例
- 接收系统发送的广播
- 示例-短信到来
- 接收系统发送的广播
- 自定义无序广播示例
- 创建广播
- 接收广播方式静态注册
- 接收广播方式代码注册
- 自定义有序广播示例
- 发送有序广播
- 接收有序广播
- 有序广播结果
- 特殊的广播接收者-锁屏等等
广播
- 听广播要有:电台 收音机 音乐广播
Android系统内部已经定义好了电台 ,也已经定义好了一些广播事件
比如外拨电话 短信到来 SD卡状态 电池电量….
使用Broadcast Receiver取接收系统已经定义好的事件
- 定义广播是为了开发者更好的开发
- 发送方和接收发可以是同一个应用程序
- 广播接收器没有用户界面
- 如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由Service 来完成
广播类型
有序广播
按照一定的优先级接收
发送优先级级别数值是在 -1000 到 1000 之间 , 值越大 , 发送的优先级越高
有序广播的数据可以被修改
有序广播的数据可以被终止
无序广播
无序广播的数据不可以被修改
无序广播的数据不可以被终止
特殊的广播接收者
操作特别频繁的广播事件,比如屏幕的锁屏和解锁,电池电量的变化 这种事件的广播在清单文件里面注册是无效的
SD卡的安装,卸载的广播,想要接收的话,需要一个约束类型,在< receiver>中
<receiver android:name="....">
<intent-filter>
<action android:name="android.intent.action.MEDIA_UNMOUNTED"></action>
<action android:name="android.intent.action.MEDIA_MOUNTED"></action>
<!--约束类型叫file sd卡的数据类型是file -->
<data android:scheme="file"></data>
</intent-filter>
</receiver>
应用程序的安装,卸载 也需要一个约束类型
<data android:scheme="package"></data>
注册广播接收者的两种方式
注意
动态注册,广播接收者的生命周期依附应用程序的生命,关闭程序,广播接收者也无效了
在清单文件里注册,广播接收者的生命会依附应用程序的进程存在,即使关闭了应用程序,进程没有销毁(没有因为内存不足销毁),广播接收者也是有效的
[1]动态注册 通过代码方式注册
private MyBroadcast myBroadcast;
......
myBroadcast = new MyBroadcast();
IntentFilter filter =new IntentFilter();
filter.addAction("......");
registerReceiver(myBroadcast,filter);
public class MyBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//接收广播后执行逻辑
}
}
@Override
protected void onDestroy() {
unregisterReceiver(screenReceiver);
super.onDestroy();
}
[2]在清单文件里通过receiver tag 节点静态发布
<receiver android:name=".SmsListenerReciver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
系统广播示例
接收系统发送的广播
[1] 定义广播接收者
public class onReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
[2]在清单文件里配置
<receiver android:name=".SmsListenerReciver"/>
[3定义过滤器具体接收什么广播
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
示例-短信到来
短信到来是一个有序广播
- 定义广播接收者
package com.peng.smslistener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
/**
* Created by Peng on 2016/7/31.
*/
public class SmsListenerReciver extends BroadcastReceiver{
//短信到来是执行
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("短信到了");
//拿到信息发送的内容和号码
Object object[] = (Object[]) intent.getExtras().get("pdus");
//循环取短信
for(Object obj:object){
//获取smsmessage实例
SmsMessage smsMessage= SmsMessage.createFromPdu((byte[]) obj);
//获取发送短信的内容
String messageBody = smsMessage.getMessageBody();
String address = smsMessage.getOriginatingAddress();
System.out.println("body:"+messageBody+address);
}
}
}
- 配置广播接收者
<receiver android:name=".SmsListenerReciver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
...
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
自定义无序广播示例
发送广播和接收广播在不同的两个应用程序中
创建广播
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View view) {
//发送无序广播
Intent intent =new Intent();
intent.setAction("com.peng.guangbo");
intent.putExtra("name","新闻联播每天晚上7点准时开播");
sendBroadcast(intent);
System.out.println("--------------->>>>>>>发送无序广播");
}
}
接收广播方式(静态注册)
public class onReceiver extends BroadcastReceiver {
//接收自定义广播
@Override
public void onReceive(Context context, Intent intent) {
//终止广播,在无序广播里没用
abortBroadcast();
String content =intent.getStringExtra("name");
Toast.makeText(context,content,Toast.LENGTH_LONG).show();
}
}
<receiver android:name="定义的接收者类名">
<intent-filter>
<action android:name="com.peng.guangbo"></action>
</intent-filter>
</receiver>
接收广播方式(代码注册)
有序和无序广播都可以通过代码注册
public class MainActivity extends AppCompatActivity {
private Mybroadcastreceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new Mybroadcastreceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.peng.guangbo");
registerReceiver(receiver,filter);
}
public class Mybroadcastreceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String content =intent.getStringExtra("name");
System.out.println(">>>>>>>>>>>动态注册");
Toast.makeText(context,content, Toast.LENGTH_LONG).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
自定义有序广播示例
发送广播和接收广播在不同的两个应用程序中
发送有序广播
假定”政府”发送一个广播,并携带数据”政府给每个村民发了1000元补贴”,这里设置了四个接收者,分别是”省长”,”市长”,”乡长”,和”农民”,优先级级别从高到低,并且会更改数据
public void click(View view) {
//点击按钮发送有序广播
Intent intent = new Intent();
intent.setAction("com.peng.sendrice");
/**
*
* 1 Intent 意图
* 2 receiverPermission 接收的权限
* 3 resultReceiver 最终的receiver
* 4 scheduler handler
* 5 initialcode 初始码
* 6initalDate 初始化数据
*/
sendOrderedBroadcast(intent,null,new FinalReceiver(),null,1,"政府给每个村民发了1000元补贴",null);
}
FinalReceiver 位于发送广播的应用程序中
这是一个resultReceiver,也是一个广播接收者,也可以理解为finalReceiver,当广播被所有接收方接收之后,才会执行这个广播接收者,相当于广播结果的反馈,它返回的是最后一个广播接收者接收的内容,在这个例子中就是”农民”的接收的数据
public class FinalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String content = getResultData();
Toast.makeText(context,"报告习大大:"+content,Toast.LENGTH_LONG).show();
}
}
接收有序广播
在清单文件里配置过滤器,接收方分别新建一个类,便于管理
如果你想在MainActivity里写广播接收者,又想在清单文件里配置,就会是这样,
<receiver android:name=".MainActivity$Mybroadcastreceiver"></receiver>
“省长”
public class ProvienceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String content = getResultData();
Toast.makeText(context,"省长:"+content,Toast.LENGTH_LONG).show();
/*
*//终止广播
*abortBroadcast();
*/
//修改广播
setResultData("政府给每个村民发了500元补贴");
}
}
“市长”
public class CityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String content = getResultData();
Toast.makeText(context,"市长:"+content,Toast.LENGTH_LONG).show();
//修改广播
setResultData("政府给每个村民发了250元补贴");
}
}
“乡长”
public class CountryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String content = getResultData();
Toast.makeText(context,"乡长:"+content,Toast.LENGTH_LONG).show();
//修改广播
setResultData("政府给每个村民发了50元补贴");
}
}
“农民”
public class NongMinReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String content = getResultData();
Toast.makeText(context,"农民:"+content,Toast.LENGTH_LONG).show();
}
}
- 清单文件里配置< reeiver>和优先级
如果通过代码注册,优先级可以这样设置
IntentFilter intentFilter =new IntentFilter();
intentFilter.addAction("......");
intentFilter.setPriority(100);
清单文件里配置
<receiver android:name=".ProvienceReceiver">
<!-- 省长-->
<intent-filter android:priority="1000">
<action android:name="com.peng.sendrice"></action>
</intent-filter>
</receiver>
<!-- 市长-->
<receiver android:name=".CityReceiver">
<intent-filter android:priority="500">
<action android:name="com.peng.sendrice"></action>
</intent-filter>
</receiver>
<!-- 乡长-->
<receiver android:name=".CountryReceiver">
<intent-filter android:priority="100">
<action android:name="com.peng.sendrice"></action>
</intent-filter>
</receiver>
<!-- 农民-->
<receiver android:name=".NongMinReceiver">
<intent-filter android:priority="-100">
<action android:name="com.peng.sendrice"></action>
</intent-filter>
</receiver>
有序广播结果
特殊的广播接收者-锁屏等等
MainActivity.java
.....
public class MainActivity extends AppCompatActivity {
private ScreenReceiver screenReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//动态的注册广播接收者
screenReceiver = new ScreenReceiver();
/*<intent-filter>
<action android:name="android.intent.action.SCREEN_ON"></action>
<action android:name="android.intent.action.SCREEN_OFF"></action>
</intent-filter>*/
//创建intentfilter对象
IntentFilter intentFilter =new IntentFilter();
//添加要注册的action
intentFilter.addAction("android.intent.action.SCREEN_ON");
intentFilter.addAction("android.intent.action.SCREEN_OFF");
//动态的注册广播接收者
registerReceiver(screenReceiver,intentFilter);
}
@Override
protected void onDestroy() {
unregisterReceiver(screenReceiver);
super.onDestroy();
}
}
ScreenReceiver.java
.....
public class ScreenReceiver extends BroadcastReceiver {
//当我们屏幕解锁和锁屏 这个方法执行
@Override
public void onReceive(Context context, Intent intent) {
//获取广播的事件类型
String action = intent.getAction();
if("android.intent.action.SCREEN_OFF".equals(action)) {
System.out.println("屏幕锁屏了");
}else if("android.intent.action.SCREEN_ON".equals(action)){
System.out.println("屏幕解锁了");
}
}
}
屏幕都关了,就不要用Toast显示屏幕锁屏数据了
广播接收者(Broadcast Receiver)