android菜鸟学习笔记26----Android广播消息及BroadcastReceiver
2015-07-15 19:32
567 查看
1.广播类型:
Android中的广播有两种类型:标准广播和有序广播。其中,标准广播是完全异步发送的广播,发出之后,几乎所有的广播接收者都会在同一时刻收到这条广播消息,因而,这种类型的广播消息是不可拦截,不可修改的;而有序广播是一种同步发送的广播,广播发出后,只有优先级最高的广播接收者能够收到这条广播消息,它处理完自己的逻辑之后,广播才会向后继续传递给低优先级的广播接收者,因此,高优先级的广播接收者可以对广播消息进行拦截,修改操作。
2.接收系统广播:
要接收系统广播,就要有自己的广播接收者。定义一个自己的广播接收者的方式就是自定义一个类继承自BroadcastReceiver,然后重写其onReceive()方法即可,在onReceive()方法中可以实现广播消息的获取,修改等操作,当然能修改的只有有序广播。
BroadcastReceiver中的常用方法:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/91cd4ee4bd21384bdd5555d3a2eb01a6.png)
getResultCode()、getResultData()、getResultExtras()分别用来获取广播的代码,数据及附加数据信息,一般是前一个广播接收者所设定的。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/4f4d50526c4ccdf03b03e5f6835db22b.png)
setXX()与上面的getXX()对应,用来进行相应的设置,后一个广播接收者获取的将是当前设置的数据。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/4e03d01b02fee6b30c6ac5e86d647803.png)
abortBradcast()截断当前广播。
2.1接收向外拨号的广播:
1)定义广播接收器并重写onReceive()方法:
2)在Manifest.xml清单文件的<application>节点下中注册广播接收者组件,声明其能接收的广播为向外拨号:
3)由于重写的onReceive()方法中修改了广播,对向外拨出的号码进行了修改,所以需要配置权限:
4)运行结果:
部署到模拟器后,然后拨号:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/9f4fbe679d1d9cc10a73d6e1254ebc83.png)
被处理之后:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/4e3ba2dc99b21f17afe812052a759ca6.png)
2.2接收网络状态变化的广播:参考《第一行代码》
1)定义广播接收器并重写onReceive()方法:
2)在Manifest.xml清单文件的<application>节点下中注册广播接收者组件:
3)需要配置权限读取网络状态的权限:
4)运行结果:
部署到模拟器后,在配置中修改网络状态:
设置为飞行模式,网络不可用:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/822f71e42f80881fed3a300688cb3019.png)
关闭飞行模式,网络变为可用:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/b96203adb6ed69dce145ed7359c8099d.png)
关闭手机移动网络:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/d90211cfc9ee84f3e1e6b331ba09fa1d.png)
开启手机移动网络:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/7717978e4a4a3f0b4eb7d7d30f998dd3.png)
3.发送广播:
需要用到Context的以下方法:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/fccd6f3bfc1a5a1bca7d49e9532261f5.png)
sendBroadcast(Intent intent):传入一个意图,然后根据意图发出一个标准广播。
sendBroadcast(Intent intent, String receiverPermission):传入一个意图及一个字符串表示的权限,指定声明改权限的广播接收者才能收到这个广播,第二个参数为null的话,表示不需要声明权限。
sendOrderedBroadcast(Intent intent, String receiverPermission):参数含义同上一个方法,不同的是该方法发送一个有序广播。
sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras):同样是发送一个有序广播,多出来的参数含义如下:
resultReceiver:指定最终的接收者,不需要则设为null
scheduler:指定自定义的Handler执行resultReceiver的回调,null则在主线程执行
initalCode:为resultCode设置初始值
initalData:为resultData设置初始值
initalExtras:为resultExtras设置初始值
3.1发送标准广播
1)修改应用的Activity,添加一个按钮,按钮的单击响应监听中发送自定义广播:
2)自定义广播接收器,接收自己发送的聚餐广播:
3)在清单文件中,配置PartyReceiver:
4)运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/e185a47c18b80c55a65f93a8442546e3.png)
3.2发送有序广播:
1)修改按钮单击事件监听:
2)新建几个接收聚餐广播的接收者:
可以直接复制原来的那个,简单修改标识即可,采用Logcat输出消息:
3)在清单文件中注册:
4)运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/bf0a688781b0189dc8715245f13dc7ed.png)
多点几次按钮,顺序仍然一样。这里没有设置优先级,就按清单文件中的顺序一个个向下传递。
5)修改清单文件,添加优先级:
6)重新运行:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/19b8b799dffa4c40a53d544afdefb26c.png)
优先级数字越大,优先级就越高。
若优先级全设置为500:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/bf0a688781b0189dc8715245f13dc7ed.png)
可见,优先级相同则按注册顺序依次传递。
7)设置不同的优先级,然后在高优先级Receiver中修改消息内容:
Receiver1:
Receiver2:
Receiver3:
8)运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/70a9e7c91913cb60015bcdf37884c8e7.png)
9)高优先级截断广播消息:
Receiver1:
运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/f87a0c1a39cd40ca53a2307d4a106f04.png)
10)设置sendOrderedBroadcast()方法的resultReceiver参数:
Receiver1中任然截获广播消息:
运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/c0aa34e3f055f912deb0ee9a0c3e402c.png)
可见,resultReceiver指定的接收者,即使高优先级接收者截获广播消息,它也一定能收到广播消息。
以上,就是学到的Android中关于广播接收者的内容。
补充:本地广播的简单使用,参考《第一行代码》
1)修改Activity代码:
主要就是之前有Context调用sendBroadcast()改为由LocalBroadcastManager调用,及注册接收者。
2)新建一个接收本地广播的接收者:
这样,这个广播就只能在本应用中可见,该应用之外不可见了。
注意一点,本地广播中这种广播接收者注册方式称之为动态注册,而前面的全局广播接收者注册是在清单文件中注册的,称之为静态注册,前面的广播接收者的注册也都可以使用动态注册,在此就不一一测试了。静态注册的好处是即使不启动应用,也能够接收广播消息进行需要的简单处理。而本地广播是当前应用发出的只在本应用内部可见的广播消息,所以只能采用动态注册,而且完全没必要采用静态注册,能发出广播消息就说明该应用已然处于启动的状态了。
Android中的广播有两种类型:标准广播和有序广播。其中,标准广播是完全异步发送的广播,发出之后,几乎所有的广播接收者都会在同一时刻收到这条广播消息,因而,这种类型的广播消息是不可拦截,不可修改的;而有序广播是一种同步发送的广播,广播发出后,只有优先级最高的广播接收者能够收到这条广播消息,它处理完自己的逻辑之后,广播才会向后继续传递给低优先级的广播接收者,因此,高优先级的广播接收者可以对广播消息进行拦截,修改操作。
2.接收系统广播:
要接收系统广播,就要有自己的广播接收者。定义一个自己的广播接收者的方式就是自定义一个类继承自BroadcastReceiver,然后重写其onReceive()方法即可,在onReceive()方法中可以实现广播消息的获取,修改等操作,当然能修改的只有有序广播。
BroadcastReceiver中的常用方法:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/91cd4ee4bd21384bdd5555d3a2eb01a6.png)
getResultCode()、getResultData()、getResultExtras()分别用来获取广播的代码,数据及附加数据信息,一般是前一个广播接收者所设定的。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/4f4d50526c4ccdf03b03e5f6835db22b.png)
setXX()与上面的getXX()对应,用来进行相应的设置,后一个广播接收者获取的将是当前设置的数据。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/4e03d01b02fee6b30c6ac5e86d647803.png)
abortBradcast()截断当前广播。
2.1接收向外拨号的广播:
1)定义广播接收器并重写onReceive()方法:
public class OutCallingReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String number = this.getResultData(); if(number.equals("10086")){ this.setResultData("110"); }else if(number.equals("10000")){ this.setResultData("120"); }else{ this.setResultData("2222"); } Toast.makeText(context, "转发成功", Toast.LENGTH_SHORT).show(); } }
2)在Manifest.xml清单文件的<application>节点下中注册广播接收者组件,声明其能接收的广播为向外拨号:
<receiver android:name="cn.csc.broadcast.OutCallingReceiver"> <intent-filter > <action android:name="android.intent.action.NEW_OUTGOING_CALL"/> </intent-filter> </receiver>
3)由于重写的onReceive()方法中修改了广播,对向外拨出的号码进行了修改,所以需要配置权限:
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
4)运行结果:
部署到模拟器后,然后拨号:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/9f4fbe679d1d9cc10a73d6e1254ebc83.png)
被处理之后:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/4e3ba2dc99b21f17afe812052a759ca6.png)
2.2接收网络状态变化的广播:参考《第一行代码》
1)定义广播接收器并重写onReceive()方法:
public class NetworkReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = connManager.getActiveNetworkInfo(); if(info != null && info.isAvailable()){ Toast.makeText(context, "网络可用", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context, "网络不可用", Toast.LENGTH_SHORT).show(); } } }
2)在Manifest.xml清单文件的<application>节点下中注册广播接收者组件:
<receiver android:name="cn.csc.broadcast.NetworkReceiver"> <intent-filter > <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> </receiver>
3)需要配置权限读取网络状态的权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
4)运行结果:
部署到模拟器后,在配置中修改网络状态:
设置为飞行模式,网络不可用:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/822f71e42f80881fed3a300688cb3019.png)
关闭飞行模式,网络变为可用:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/b96203adb6ed69dce145ed7359c8099d.png)
关闭手机移动网络:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/d90211cfc9ee84f3e1e6b331ba09fa1d.png)
开启手机移动网络:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/7717978e4a4a3f0b4eb7d7d30f998dd3.png)
3.发送广播:
需要用到Context的以下方法:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/fccd6f3bfc1a5a1bca7d49e9532261f5.png)
sendBroadcast(Intent intent):传入一个意图,然后根据意图发出一个标准广播。
sendBroadcast(Intent intent, String receiverPermission):传入一个意图及一个字符串表示的权限,指定声明改权限的广播接收者才能收到这个广播,第二个参数为null的话,表示不需要声明权限。
sendOrderedBroadcast(Intent intent, String receiverPermission):参数含义同上一个方法,不同的是该方法发送一个有序广播。
sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras):同样是发送一个有序广播,多出来的参数含义如下:
resultReceiver:指定最终的接收者,不需要则设为null
scheduler:指定自定义的Handler执行resultReceiver的回调,null则在主线程执行
initalCode:为resultCode设置初始值
initalData:为resultData设置初始值
initalExtras:为resultExtras设置初始值
3.1发送标准广播
1)修改应用的Activity,添加一个按钮,按钮的单击响应监听中发送自定义广播:
Button btn = (Button) findViewById(R.id.btn_send_normal); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent("cn.csc.broadcast.PARTY"); intent.putExtra("content", "明天下午16点校南门集合,一起去龙湖看电影,聚餐"); sendBroadcast(intent); } });
2)自定义广播接收器,接收自己发送的聚餐广播:
public class PartyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Toast.makeText(context, intent.getStringExtra("content"), Toast.LENGTH_LONG).show(); } }
3)在清单文件中,配置PartyReceiver:
<receiver android:name="cn.csc.broadcast.PartyReceiver"> <intent-filter > <action android:name="cn.csc.broadcast.PARTY"/> </intent-filter> </receiver>
4)运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/e185a47c18b80c55a65f93a8442546e3.png)
3.2发送有序广播:
1)修改按钮单击事件监听:
sendOrderedBroadcast(intent, null, null, null, 0, "明天下午16点校南门集合,一起去龙湖看电影,聚餐", null);
2)新建几个接收聚餐广播的接收者:
可以直接复制原来的那个,简单修改标识即可,采用Logcat输出消息:
public class PartyReceiver1 extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Log.i("PARTY","F1:"+ getResultData()); } }
3)在清单文件中注册:
<receiver android:name="cn.csc.broadcast.PartyReceiver1"> <intent-filter > <action android:name="cn.csc.broadcast.PARTY"/> </intent-filter> </receiver> <receiver android:name="cn.csc.broadcast.PartyReceiver2"> <intent-filter > <action android:name="cn.csc.broadcast.PARTY"/> </intent-filter> </receiver> <receiver android:name="cn.csc.broadcast.PartyReceiver3"> <intent-filter > <action android:name="cn.csc.broadcast.PARTY"/> </intent-filter> </receiver>
4)运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/bf0a688781b0189dc8715245f13dc7ed.png)
多点几次按钮,顺序仍然一样。这里没有设置优先级,就按清单文件中的顺序一个个向下传递。
5)修改清单文件,添加优先级:
<receiver android:name="cn.csc.broadcast.PartyReceiver1"> <intent-filter android:priority="0"> <action android:name="cn.csc.broadcast.PARTY"/> </intent-filter> </receiver> <receiver android:name="cn.csc.broadcast.PartyReceiver2"> <intent-filter android:priority="500"> <action android:name="cn.csc.broadcast.PARTY"/> </intent-filter> </receiver> <receiver android:name="cn.csc.broadcast.PartyReceiver3"> <intent-filter android:priority="1000"> <action android:name="cn.csc.broadcast.PARTY"/> </intent-filter> </receiver>
6)重新运行:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/19b8b799dffa4c40a53d544afdefb26c.png)
优先级数字越大,优先级就越高。
若优先级全设置为500:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/bf0a688781b0189dc8715245f13dc7ed.png)
可见,优先级相同则按注册顺序依次传递。
7)设置不同的优先级,然后在高优先级Receiver中修改消息内容:
Receiver1:
Log.i("PARTY","F1:"+getResultData()); setResultData("明天早上5点校西门集合,一起去春熙路看美女");
Receiver2:
Log.i("PARTY","F2:"+getResultData()); setResultData("明天自由活动");
Receiver3:
Log.i("PARTY","F3:"+getResultData());
8)运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/70a9e7c91913cb60015bcdf37884c8e7.png)
9)高优先级截断广播消息:
Receiver1:
Log.i("PARTY","F1:"+getResultData()); setResultData("明天早上5点校西门集合,一起去春熙路看美女");
abortBroadcast();
运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/f87a0c1a39cd40ca53a2307d4a106f04.png)
10)设置sendOrderedBroadcast()方法的resultReceiver参数:
sendOrderedBroadcast(intent, null, new PartyReceiver3(), null, 0, "明天下午16点校南门集合,一起去龙湖看电影,聚餐", null);
Receiver1中任然截获广播消息:
Log.i("PARTY","F1:"+getResultData()); setResultData("明天早上5点校西门集合,一起去春熙路看美女");
abortBroadcast();
运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201507/c0aa34e3f055f912deb0ee9a0c3e402c.png)
可见,resultReceiver指定的接收者,即使高优先级接收者截获广播消息,它也一定能收到广播消息。
以上,就是学到的Android中关于广播接收者的内容。
补充:本地广播的简单使用,参考《第一行代码》
1)修改Activity代码:
public class MainActivity extends ActionBarActivity { private LocalBroadcastManager manager; private LocalReceiver localReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.btn_send_normal); manager = LocalBroadcastManager.getInstance(this); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent("cn.csc.broadcast.PARTY"); intent.putExtra("content", "明天下午16点校南门集合,一起去龙湖看电影,聚餐"); manager.sendBroadcast(intent); } }); IntentFilter filter = new IntentFilter(); filter.addAction("cn.csc.broadcast.PARTY"); localReceiver = new LocalReceiver(); manager.registerReceiver(localReceiver, filter); } @Override protected void onDestroy() { // TODO Auto-generated method stub manager.unregisterReceiver(localReceiver); } }
主要就是之前有Context调用sendBroadcast()改为由LocalBroadcastManager调用,及注册接收者。
2)新建一个接收本地广播的接收者:
public class LocalReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Toast.makeText(context, intent.getStringExtra("content"), Toast.LENGTH_LONG).show(); } }
这样,这个广播就只能在本应用中可见,该应用之外不可见了。
注意一点,本地广播中这种广播接收者注册方式称之为动态注册,而前面的全局广播接收者注册是在清单文件中注册的,称之为静态注册,前面的广播接收者的注册也都可以使用动态注册,在此就不一一测试了。静态注册的好处是即使不启动应用,也能够接收广播消息进行需要的简单处理。而本地广播是当前应用发出的只在本应用内部可见的广播消息,所以只能采用动态注册,而且完全没必要采用静态注册,能发出广播消息就说明该应用已然处于启动的状态了。
相关文章推荐
- android 视图getParent,getChildAt
- android studio 更新 Gradle错误解决方法
- ArrayAdapter中的android.R.id.text1是什么
- 辗转到了Android
- Android Intents with Chrome
- Android 录音
- Android 你应该知道的学习资源 进阶之路贵在坚持
- android MediaRecorder 与 AudioRecord 差异
- Android在ListView滑动数据混乱
- Android - Launcher Icon Size
- Android系统匿名共享内存Ashmem
- Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager
- Android系统的定制
- Android ImageView.ScaleType说明
- Android:Layout_weight的深刻理解
- 如何提高Android应用启动速度,避免启动时黑屏太久
- Android 文字竖排效果
- Android ExpandableListView的使用
- 大约Android远程监控APP源代码
- android开发之AlertDialog点击按钮之后不消失