andorid Broadcast Receiver
来源:互联网 发布:合众思壮软件 编辑:程序博客网 时间:2024/06/16 01:57
转:http://blog.csdn.net/anddlecn/article/details/51741455
自定义Broadcast Receiver
无论是应用还是系统组件,它们定义Broadcast Receiver
的方式都是一样。
定义Broadcast Receiver
有两种方式,
静态定义:将
Broadcast Receiver
声明到AndroidManifest.xml
配置文件当中,它的特点是应用不必运行起来,系统能通过配置文件的描述判断当前系统中的广播是否是这台接收机关注的;动态定义:在代码中动态生成
Broadcast Receiver
,它的特点是应用要运行起来,在运行的过程当中判断当前系统中的广播是否是这台接收机关注的;
静态Broadcast Receiver
首先来看看如何定义一个静态的Broadcast Receiver
。
继承
BroadcastReceiver
类,实现它的onReceive
接口,public class MyReceiver extends BroadcastReceiver { public MyReceiver() { } //实现onReceive接口,当收到指定的广播后被触发 @Override public void onReceive(Context context, Intent intent) { //添加对应的逻辑处理 }}
2.在AndroidManifest.xml
配置文件当中,声明创建的Broadcast Receiver
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="custom.action.mybroadcast"/> ---指定关注的广播 <category android:name="android.intent.category.DEFAULT" /> </intent-filter></receiver>
这里intent-filter
标签中的action android:name
属性设置的值custom.action.mybroadcast
,就是这台接收机
关注的广播。
当名称为custom.action.mybroadcast
的广播在系统中传播的时候,MyReceiver
就会被运行起来,并触发它的onReceive()
函数。开发者就需要在这里添加对应逻辑处理。
动态Broadcast Receiver
当应用运行起来以后,即使AndroidManifest.xml
文件中没有声明过Broadcast Receiver
也没有关系,它可以被动态的创建,
和创建静态
Broadcast Receiver
类似,首先要继承BroadcastReceiver
类,实现它的onReceive
接口,
public class MyReceiver extends BroadcastReceiver { public MyReceiver() { } //实现onReceive接口,当收到指定的广播后被触发 @Override public void onReceive(Context context, Intent intent) { //添加对应的逻辑处理 }}
2.注册Broadcast Receiver
,并告诉系统这个Broadcast Receiver
关注哪些广播,可以添加多种关心的广播,
//设置过滤器,确定关心的广播IntentFilter filter = new IntentFilter();filter.addAction("custom.action.mybroadcast");//可以添加多种关心的广播filter.addAction(......);//创建ReceiverMyReceiver receiver = new MyReceiver();//注册到系统当中,完成Receiver的设置registerReceiver(receiver, filter);
3.使用完毕后,一定要注销Broadcast Receiver
,否则系统会给出警告提示。
unregisterReceiver(receiver);动态的
Broadcast Receiver
在注册使用完成之后一定要注销,不然会占用系统资源、浪费资源。发送Broadcast
发送出去的广播可以分成两类,一类是无序广播,一类是有序广播。无序广播
这是一种不需要考虑接收者接收顺序的广播,比如说有3个接收机
,都关注custom.action.mybroadcast
这种广播,无所谓谁先收到谁后收到。接收机
不能阻止其它接收机
获取到这条广播。
1 发送
发送无序广播,只要使用Context
的sendBroadcast()
方法就可以了,
Intent intent = new Intent(); //广播中的action也是自定义的 intent.setAction("custom.action.mybroadcast"); sendBroadcast(intent);
2 接收<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="custom.action.mybroadcast"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter></receiver>
在AndroidManifest.xml
中声明静态Broadcast Receiver
的时候,
有序广播
这是一种需要考虑接收者接收顺序的广播,比如说有3个接收机
,都关注custom.action.mybroadcast
这种广播,那么安卓系统将根据这3个接收机
声明的优先级进行广播的投递。
而且有序广播是可以被阻截的。
比如,一个广播按照顺序传递给3个接收机
-A B C,但是B将广播拦截了,因此C将不会收到这个广播。
1.发送
Intent i = new Intent("custom.action.mybroadcast");sendOrderedBroadcast(i, null);
2.接收
接收的时候,需要给intent-filter
标签设置android:priority
属性,表示这个接收机
的优先级。优先级从-1000到1000,数值越大,优先级越高。
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="1000"> <action android:name="custom.action.mybroadcast"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter></receiver>
接收到广播以后,Broadcast Receiver
可以将广播拦截,禁止它往下传播,
public class MyReceiver extends BroadcastReceiver { public MyReceiver() { } //实现onReceive接口 @Override public void onReceive(Context context, Intent intent) { //禁止往下传播 abortBroadcast(); }}
如果接收机1
在onReceive()
中,希望把数据传递给下个接收机2
,
接收机1
可以使用setResultExtras()
方法,
public class MyReceiver1 extends BroadcastReceiver { public MyReceiver() { } @Override public void onReceive(Context context, Intent intent) { Bundle b = new Bundle(); b.putString("data", "this data from MyReceiver"); setResultExtras(b); }}
在
接收机2
中,public class MyReceiver2 extends BroadcastReceiver { public MyReceiver2() { } @Override public void onReceive(Context context, Intent intent) { Bundle b = getResultExtras(true); if(b!=null) { //data就是前一个接收机1传来的-this data from MyReceiver String data = b.getString("data"); } }}
假如希望将数据放到onReceive()
传入的Intent
当中,是不会传递成功的,
@Overridepublic void onReceive(Context context, Intent intent) { //这是不会成功的 intent.putExtra("data", "this data from MyReceiver");}
传递数据,一定要通过BroadcastReceiver
提供的setResultExtras()
方法。
有序广播例子
public void onClick1(View view) { Intent intent = new Intent(); intent.setAction("com.example.zdy"); //发送有序广播 //resultReceiver:不需要在清单文件中配置,这个广播接收者只接受该条有序广播,并且是最后一个收到该广播,并且一定可以收到该广播 sendOrderedBroadcast(intent, null, new MyReceiver(), null, 0, "每人发100元", null); } // class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String text = getResultData(); System.out.println("广播接收者处理后的结果:" + text); } }
广播接收者
public class ShengZF extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String text = getResultData(); System.out.println("ShengZF收到广播:" + text); setResultData("每人发80元"); }}
public class ShiZF extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { String text = getResultData(); System.out.println("ShiZF收到"+text); abortBroadcast();//拦截广播 }}
public class XianZF extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { String text = getResultData(); System.out.println("XianZF:"+text); }}
<receiver android:name="com.example.location.ShengZF"> <intent-filter android:priority="1000"> <action android:name="com.example.zdy"></action> </intent-filter> </receiver> <receiver android:name="com.example.location.ShiZF"> <intent-filter android:priority="100"> <action android:name="com.example.zdy"></action> </intent-filter> </receiver> <receiver android:name="com.example.location.XianZF"> <intent-filter android:priority="0"> <action android:name="com.example.zdy"></action> </intent-filter> </receiver>
-----------------------------------=============================
#IP拨号器
> 原理:接收拨打电话的广播,修改广播内携带的电话 号码
* 定义广播接收者接收打电话广播
public class CallReceiver extends BroadcastReceiver {
//当广播接收者接收到广播时,此方法会调用
@Override
public void onReceive(Context context, Intent intent) {
//拿到用户拨打的号码
String number = getResultData();
//修改广播内的号码
setResultData("17951" + number);
}
}
* 在清单文件中定义该广播接收者接收的广播类型
<receiver android:name="com.itheima.ipdialer.CallReceiver">
<intent-filter >
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
* 接收打电话广播需要权限
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
* 即使广播接收者的进程没有启动,当系统发送的广播可以被该接收者接收时,系统会自动启动该接收者所在的进程
#短信拦截器
>系统收到短信时会产生一条广播,广播中包含了短信的号码和内容
* 定义广播接收者接收短信广播
public void onReceive(Context context, Intent intent) {
//拿到广播里携带的短信内容
Bundle bundle = intent.getExtras();
Object[] objects = (Object[]) bundle.get("pdus");
for(Object ob : objects ){
//通过object对象创建一个短信对象
SmsMessage sms = SmsMessage.createFromPdu((byte[])ob);
System.out.println(sms.getMessageBody());
System.out.println(sms.getOriginatingAddress());
}
}
* 系统创建广播时,把短信存放到一个数组,然后把数据以pdus为key存入bundle,再把bundle存入intent
* 清单文件中配置广播接收者接收的广播类型,注意要设置优先级属性,要保证优先级高于短信应用,才可以实现拦截
<receiver android:name="com.itheima.smslistener.SmsReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
* 添加权限
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
---
#监听SD卡状态
* 清单文件中定义广播接收者接收的类型,监听SD卡常见的三种状态,所以广播接收者需要接收三种广播
<receiver android:name="com.itheima.sdcradlistener.SDCardReceiver">
<intent-filter >
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
<action android:name="android.intent.action.MEDIA_REMOVED"/>
<data android:scheme="file"/>
</intent-filter>
</receiver>
* 广播接收者的定义
public class SDCardReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 区分接收到的是哪个广播
String action = intent.getAction();
if(action.equals("android.intent.action.MEDIA_MOUNTED")){
System.out.println("sd卡就绪");
}
else if(action.equals("android.intent.action.MEDIA_UNMOUNTED")){
System.out.println("sd卡被移除");
}
else if(action.equals("android.intent.action.MEDIA_REMOVED")){
System.out.println("sd卡被拔出");
}
}
}
---
#勒索软件
* 接收开机广播,在广播接收者中启动勒索的Activity
* 清单文件中配置接收开机广播
<receiver android:name="com.itheima.lesuo.BootReceiver">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
* 权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
* 定义广播接收者
@Override
public void onReceive(Context context, Intent intent) {
//开机的时候就启动勒索软件
Intent it = new Intent(context, MainActivity.class);
context.startActivity(it);
}
* 以上代码还不能启动MainActivity,因为广播接收者的启动,并不会创建任务栈,那么没有任务栈,就无法启动activity
* 手动设置创建新任务栈的flag
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
---
#监听应用的安装、卸载、更新
> 原理:应用在安装卸载更新时,系统会发送广播,广播里会携带应用的包名
* 清单文件定义广播接收者接收的类型,因为要监听应用的三个动作,所以需要接收三种广播
<receiver android:name="com.itheima.app.AppReceiver">
<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>
- andorid Broadcast Receiver
- broadcast receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- Broadcast Receiver
- BroadCast Receiver
- Broadcast Receiver
- broadcast与broadcast receiver
- Intent、Broadcast Receiver、service
- 网站盗链问题及解决方案
- Decode String
- Leetcode006--字符串的Z字型打印
- android 编译错误 Error:(1, 0) Plugin with id 'com.android.application' not found. 解决
- rmtp流中对音频数据头的解析。
- andorid Broadcast Receiver
- git学习
- spring注解
- Redis事务
- POJ 2823 Sliding Window 翻译
- 可恶的四级
- Markdown——入门指南
- 【程序员面试金典】基本字符串压缩
- Android从零开始构建项目之目录结构