1.BroadcastReceiver简介
Android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。而作为应用开发者,就需要熟练掌握Android系统提供的一个开发利器,那就是BroadcastReceiver
注意点
1,发送频率低的可以使用
2,数据量小在可使用
面试题 Android引入广播的用意
a:从MVC的角度考虑(应用程序内)其实回答这个问题的时候还可以这样问,android为什么要有那4大组件,现在的移动开发模型基本上也是照搬的web那一套MVC架构,只不过是改了点嫁妆而已。android的四大组件本质上就是为了实现移动或者说嵌入式设备上的MVC架构,它们之间有时候是一种相互依存的关系,有时候又是一种补充关系,引入广播机制可以方便几大组件的信息和数据交互。
b:程序间互通消息(例如在自己的应用程序内监_听系统来电)
c:效率上(参考UDP的广播协议在局域网的方便性)
2.广播接收者的创建
public class MyReceiver2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "接收到广播就下课", Toast.LENGTH_SHORT).show();
}
}
注册
静态注册
特点: 当程序退出后,广播依然存在,直至应用被卸载
<receiver android:name="com.example.bcreceiver.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_BROADCAST" /> //这里的name可以随便写
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver
也可以通过AS创建BroadcastReceive,AS会自动帮你静态注册
<receiver
android:name=".JudgeNetIsConnectedReceiver"
android:enabled="true"
android:exported="true"></receiver>
// android:exported="true" 是否只接收本应用的广播
动态注册
特点:该广播只在应用中有效,退出后不再接收广播
动态注册需要在代码中动态的指定广播地址并注册
MyBroadcastReceiver mbcr = new MyBroadcastReceiver();
项目中常用代码(重点)
/**
* 自定义BaseActivity用来创建广播和销毁广播
* @author dell
*
*/
public abstract class BaseActivity extends FragmentActivity {
/**
* 声明判断网络是否连接成功的接受者对象
*/
private JudgeNetIsConnectedReceiver judgeNetIsConnectedReceiver;
@Override
protected void onCreate(Bundle bundle) {
// TODO Auto-generated method stub
super.onCreate(bundle);
this.judgeNetIsConnectedReceiver=new JudgeNetIsConnectedReceiver();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
IntentFilter intentFilter=new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
this.registerReceiver(judgeNetIsConnectedReceiver, intentFilter);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if(this.judgeNetIsConnectedReceiver!=null){
this.unregisterReceiver(judgeNetIsConnectedReceiver);
}
}
}
连接管理器对象
ConnectivityManager 主要管理网络连接的相关的类
它主要负责的是
1 监视网络连接状态 包括(Wi-Fi, GPRS, UMTS, etc)
2 当网络状态改变时发送广播通知
3 当网络连接失败尝试连接其他网络
4提供API,允许应用程序获取可用的网络状态
获取方法是 Context.getSystemService(Context.CONNECTIVITY_SERVICE)
常用方法
NetworkInfo getActiveNetworkInfo()
返回当前网络的详细信息
boolean getBackgroundDataSetting()
API上说在1.4以后已经被启用了,调用后总返回的是true
NetworkInfo getNetworkInfo(int networkType)
这个方法是获取networkType的状态信息,例如获取手机WIFI信息可以这样写
ConnectivityManager mConnectivity = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
System.out.println(mConnectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI));
如果手机有WIFI的话返回的结果如下
NetworkInfo: type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: (none), roaming: false,
failover: false, isAvailable: true
没有WIFI:
NetworkInfo: type: WIFI[], state: DISCONNECTED/DISCONNECTED, reason: (unspecified), extra: (none), roaming: false,
failover: false, isAvailable: false
TYPE_BLUETOOTH 蓝牙
TYPE_MOBILE 默认网络连接
String | CONNECTIVITY_ACTION |
在网络连接中出现的一个变化。已被建立或断开的一个连接。 | |
如果当前网络是从无法连接的网络切换到可连接的网络,那么FAILOVER_CONNECTION被设置为true。NetworkInfo会受网络影响而被额外地发送,它可以查询到网络连接的相关信息。 | |
当网络连接失败,连接管理器试图去连接(或已连接)到另一个网络,那么NetworkInfo会因为这个新网络而被额外的通过。这种情况下,广播的接收类不需要告诉使用者们当前没有数据流量。反之,这个接收类立即等待另一个指示网络切换成功(整体数据连接)或切换失败(所有的数据连接已丢失)的广播。 | |
返回的常数值:”android.net.conn.CONNECTIVITY_CHANGE” | |
String | EXTRA_EXTRA_INFO |
说明:提供网络状态的额外信息查询关键字符串。这些信息可能从脚底的网络层传出,对于特定的网络类型来说它的意义可能是特定的。通过 getStringExtra(String)来获取。 | |
返回的常数值:”extraInfo” | |
String | EXTRA_IS_FAILOVER |
String | EXTRA_EXTRA_INFO |
说明:是一个获取布尔值的查询关键字。它指的是在网络断开时,网络连接管理器是否成功切换到另一个可用网络。通过getBooleanExtra(String, boolean)查询。 | |
返回的常数值:”isFailover” | |
String | EXTRA_NETWORK_INFO |
这个常数在API14(Android 4.0)时已弃用。 | |
说明:由于NetworkInfo基于UID(每个软件安装在手机的时候,手机都会分配一个UID为唯一标示)的不同而不同,应用程序可以通过getActiveNetworkInfo()或getAllNetworkInfo()来获取网络信息。 | |
可以通过getParcelableExtra(String)获取NetworkInfo的对象的查找键。参见EXTRA_NETWORK_TYPE。 | |
返回的常数值:”EXTRA_NETWORK_TYPE” | |
String | EXTRA_NETWORK_INFO |
说明:可以出发CONNECTIVITY_ACTION广播的网络类型。在调用应用程序的基础上与 getNetworkInfo(int)一起使用来获取NetworkInfo的状态。参见getIntExtra(String, int)。 | |
返回的常数值:”networkType” | |
String | EXTRA_NO_CONNECTIVITY |
说明:一个布尔值的查找键,指是否存在一个完整的连接缺陷,即没有网络可以。通过getBooleanExtra(String, boolean)来查找。 | |
返回的常数值:”noConnectivity” | |
String | EXTRA_OTHER_NETWORK_INFO |
说明:一个NetworkInfo的对象查找键。当存在另一个可连接的网络时被提供。通过getParcelableExtra(String)获取。 | |
返回的常数值:”otherNetwork” | |
String | EXTRA_REASON |
说明:用于表示网络连接失败的字符串查找键。该字符串没有特定的结构。它的目的是用于向用户提交的通知。通过getStringExtra(String)获取。 | |
返回的常数值:”reason” | |
int | DEFAULT_NETWORK_PREFERENCE |
这个常数在API18(Android 4.3)时已弃用。 | |
说明:由于现在支持的网络较多,默认的单一网络偏好不能真正地表达网络层次。默认值在config.xml中通过networkAttributes来定义的。在应用程序中通过调用getNetworkPreference()来获取当前值。 | |
如果你想设置默认的网络偏好,那么可以直接搞遍框架中config.xml中的networkAttributes。 | |
返回的常数值:1 (0x00000001) | |
int | TYPE_BLUETOOTH |
说明:蓝牙数据连接。当被使用时,所有的数据流将默认使用这个网络类型的接口。 | |
返回的常数值:7 (0x00000007) | |
int | TYPE_DUMMY |
说明:虚拟数据连接。这个不应该是使用在运输设备上。 | |
返回的常数值:8 (0x00000008) | |
int | TYPE_ETHERNET |
说明:以太网(局域网的一种)数据连接。当被使用时,所有数据流将默认使用这个网络类型的接口(它有一个默认的路径)。 | |
返回的常数值:9 (0x00000009) | |
int | TYPE_MOBILE |
说明:移动数据连接。当被使用时,所有数据流将默认使用这个网络类型的接口(它有一个默认的路径)。 | |
返回的常数值:0 (0x00000000) | |
int | TYPE_MOBILE_DUN |
说明:特殊拨号联网的移动数据连接。这个网络类型可以使用与TYPE_MOBILE相同的网络接口,也可以使用不同的。 | |
返回的常数值:4 (0x00000004) | |
int | TYPE_MOBILE_HIPRI |
说明:高优先级的移动数据连接。这种网络类型使用的网络接口与TYPE_MOBILE相同但路由设置不同。只有在请求的过程中才会获取移动的DNS服务器(Domain Name Server,域名服务器),如果没有没有默认路径存在,那么只能通过IP的明确要求通过requestRouteToHost(int, int)方法来导入这个接口。 | |
返回的常数值:5 (0x00000005) | |
int | TYPE_MOBILE_MMS |
说明:多媒体移动数据连接。这个网络类型可以使用与TYPE_MOBILE相同的网络接口,也可以使用不同的。这个在应用系统需要与运营商的多媒体消息服务的服务器进行通话时使用。 | |
返回的常数值:2 (0x00000002) | |
int | TYPE_MOBILE_SUPL |
说明:SUPL移动数据连接。(SUPL,secure user plane location, 用于移动电话和定位服务器之间进行通信的协议标准,作为OMA的标准。)这个网络类型可以使用与TYPE_MOBILE相同的网络接口,也可以使用不同的。这个在应用程序需要通过与运营商的SUPL服务通话来请求定位时使用。 | |
返回的常数值:3 (0x00000003) | |
int | TYPE_WIFI |
说明:无线数据连接。当被使用时,所有数据流将默认使用这个网络类型的接口(它有一个默认的路径)。 | |
返回的常数值:1 (0x00000001) | |
int | TYPE_WIMAX |
WIMAX(Worldwide Interoperability for Microwave Access,即全球微波互联接入)数据连接。当被使用时,所有数据流将默认使用这个网络类型的接口(它有一个默认的路径)。 | |
返回的常数值:6 (0x00000006) |
- 公共方法
NetworkInfo | getActiveNetworkInfo() |
---|---|
说明:返回当前活动的默认数据网络的详细信息。当连接时,对于其它网络,这个网络是默认的路径。你只要在使用网络流量前通过isConnected()来查询是否连接。当它返回的是null,那么当前没有默认的网络。 | |
返回一个当前默认网络的NetworkInfo对象或者在网络时返回null。 | |
该方法需要持有ACCESS_NETWORK_STATE的许可。 | |
NetworkInfo[] | getAllNetworkInfo() |
说明:返回设备支持的所有网络类型的连接状态信息。 | |
返回一个NetworkInfo数组。通过getType()来获取每一个应用的类型。 | |
该方法需要持有ACCESS_NETWORK_STATE的许可。 | |
boolean | getBackgroundDataSetting () |
说明:该方法在API14(Android 4.0)时已弃用。 | |
NetworkInfo | getNetworkInfo (int networkType) |
说明:返回一个请求网络类型的NetworkInfo连接状态的对象,如果当前设备不支持这个networkType参数指定的网络类型那么返回null。 | |
该方法需要持有ACCESS_NETWORK_STATE的许可。 | |
int | getNetworkPreference () |
说明:获取当前首选的网络类型。要注意的是,该方法只有在两个网络类型的情况下有意义,随着默认的网络类型越来越多,我们需要一个数组来列出它们的顺序。这个方法将很快被淘汰。 | |
该方法需要持有ACCESS_NETWORK_STATE的许可。 | |
boolean | isActiveNetworkMetered () |
说明:当用户在该连接上使用大量数据,由于成本、数据的局限性和电池/性能的问题,这个网络被归类于计量。在做大量数据传输之前,您应该要检查并警告用户或延迟的另一个网络可用时再操作。 | |
如果要避免大量的传输,那么返回true,否则返回false。 | |
该方法需要持有ACCESS_NETWORK_STATE的许可。 | |
static boolean | isNetworkTypeValid (int networkType) |
说明:测试一个指定的网络类型是否是有效。 | |
boolean | requestRouteToHost (int networkType, int hostAddress) |
说明:添加指定的网络接口向指定的主机提供流量的网络路由。添加已存在的路由会被忽略,但视为成功。 | |
该方法需要持有CHANGE_NETWORK_STATE的许可。 | |
void | setNetworkPreference (int preference) |
说明:设置首选的网络类型。当设备有一个以上的网络可用,那么首选的网络类型将被使用。要注意的是,该方法只有在两个网络类型的情况下有意义,随着默认的网络类型越来越多,我们需要一个数组来列出它们的顺序。这个方法将很快被淘汰。 | |
int | startUsingNetworkFeature (int networkType, String feature) |
说明:告诉顶层网络系统,调用方希望开始使用指定的功能。功能的特征完全取决于每一个网络的实现。 | |
返回一个表示请求结果的整数值。此值的解释是特定于每一个网络实现+功能的组合,除了-1表示的是失败。 | |
该方法需要持有CHANGE_NETWORK_STATE的许可。 | |
int | stopUsingNetworkFeature (int networkType, String feature) |
说明:告诉顶层网络系统,调用方使用指定的功能完成。功能的特征完全取决于每一个网络的实现。 | |
返回一个表示请求结果的整数值。此值的解释是特定于每一个网络实现+功能的组合,除了-1表示的是失败。 | |
该方法需要持有CHANGE_NETWORK_STATE的许可。 |
利用广播接收者判断网络连接
public class JudgeNetIsConnectedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//得到网络是否连接成功
/**
* 下面的判断是要支持网络请求的时候才会发送广播,是有延时的
* 而上面的是网络一断开系统就立即发送广播,是即时的
* 将这2个判断连中一起就是完美的判断
* ConnectivityManager.EXTRA_NO_CONNECTIVITY:
* 一个布尔值的查找键,指是否存在一个完整的连接缺陷,即没有网络可以。
* 通过getBooleanExtra(String, boolean)来查找。
*/
boolean isNotConnected = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,false);
if (!isNotConnected || judgeNetIsConnected(context)){
Toast.makeText(context, "网络连接成功!", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "您的网络不给力,请检查网络!", Toast.LENGTH_LONG).show();
}
}
/**
* 判断网络连接是否成功
* @param context 上下文对象
* @return 网络连接是否成功
*/
public static boolean judgeNetIsConnected(Context context) {
//得到连接管理器对象
ConnectivityManager connectivityManager= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
//返回当前网络的详细信息
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if(info==null){
return false;
}
return info.isConnected();
}
}
在activity中动态注册和注销
public class BaseActivity extends FragmentActivity{
//声明一个(判断网是否连接的)广播接收者
private JudgeNetIsConnectedReceiver judgeNetIsConnectedReceiver;
@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
//实例化广播接收者
JudgeNetIsConnectedReceiver judgeNetIsConnectedReceiver = new JudgeNetIsConnectedReceiver();
}
@Override
protected void onResume() {
super.onResume();
//动态注册广播接收者
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
this.registerReceiver(judgeNetIsConnectedReceiver,intentFilter);
}
//ConnectivityManager.CONNECTIVITY_ACTION) :在网络连接中出现的一个变化。已被建立或断开的一个连接。
@Override
protected void onPause() {
super.onPause();
//取消广播的发送
this.unregisterReceiver(judgeNetIsConnectedReceiver);
}
}