Android开发笔记(六十)网络的检测与连接

本文详细介绍了在Android平台上如何检测网络状态,连接WiFi,使用反射技术以及开启个人热点的功能,并提供了相应的代码示例。
摘要由CSDN通过智能技术生成

检测网络

APP在访问网络之前,正常都要先检测网络状态,因为如果未连接网络就上网的话,常常导致超时等待。另外,APP有时也需区分当前网络是wifi环境还是数据连接环境,如果是数据连接环境,那么为了节省流量,一般不进行下载操作也不加载大图片;如果是wifi环境,那就都可以做而不必担心消耗流量。


ConnectivityManager就是用于检测网络连接的工具类,其对象从系统服务Context.CONNECTIVITY_SERVICE中获取。该类的常用方法是getActiveNetworkInfo,调用该方法返回一个NetworkInfo对象,下面是NetworkInfo的常用方法:
getType : 获取网络类型。ConnectivityManager.TYPE_WIFI表示wifi,ConnectivityManager.TYPE_MOBILE表示数据连接,ConnectivityManager.TYPE_WIMAX表示wimax,ConnectivityManager.TYPE_ETHERNET表示以太网,ConnectivityManager.TYPE_BLUETOOTH表示蓝牙。
getState : 获取网络状态。State.CONNECTING表示正在连接,State.CONNECTED表示已连接,State.SUSPENDED表示挂起,State.DISCONNECTING表示正在断开,State.DISCONNECTED表示已断开,State.UNKNOWN表示未知。
getSubtype : 获取网络子类型。当网络类型为数据连接时,子类型为2G/3G/4G的细分类型,如CDMA、EVDO、HSDPA、LTE等等。


当网络类型是wifi时,要想获取详细的wifi信息,又得使用WifiManager,该类的对象从系统服务Context.WIFI_SERVICE中获取。下面是WifiManager的常用网络检测方法:
isWifiEnabled : 判断WLAN功能是否开启
setWifiEnabled : 开关WLAN功能
getWifiState : 获取当前wifi的状态。WIFI_STATE_DISABLED表示已断开,WIFI_STATE_DISABLING表示正在断开,WIFI_STATE_ENABLED表示已连上,WIFI_STATE_ENABLING表示正在连接,WIFI_STATE_UNKNOWN表示未知。
getConnectionInfo : 获取当前wifi的连接信息。该方法返回一个WifiInfo对象,WifiInfo可通过相应的get方法获取如下信息:wifi名称、路由器MAC、WIFI信号强度、连接速率、IP地址、MAC地址、网络编号等等。


连接wifi

下面是WifiManager的常用网络检测方法:
startScan : 开始扫描周围的wifi信息。
getScanResults : 获取周围wifi的扫描结果。
calculateSignalLevel : 根据信号强度计算信号等级。
getConfiguredNetworks : 获取已配置的网络信息。
addNetwork : 添加指定wifi配置。
enableNetwork : 启用指定wifi。第二个参数表示是否同时禁用其他的wifi
disableNetwork : 禁用指定wifi。
disconnect : 断开当前wifi。


要连上某个具体的wifi,实际开发中的调用顺序为:首先调用startScan开始扫描周围wifi,然后调用getScanResults获取扫描的wifi列表,接着通过getConfiguredNetworks查找已配置的网络信息;如果找到指定的网络配置,则调用enableNetwork启用该wifi;如果没找到指定wifi配置,则先调用addNetwork添加wifi配置(addNetwork会返回一个网络ID来标识刚添加的wifi),然后调用enableNetwork启用该wifi。
需要注意的是,在addNetwork之前还得创建新的wifi配置信息,即一个WifiConfiguration实例。WifiConfiguration的赋值比较难懂,就不费口舌了,直接上代码:
	private WifiConfiguration createWifiInfo(String ssid, String password, int type) {
		WifiConfiguration config = new WifiConfiguration();
		config.SSID = "\"" + ssid + "\"";
		if (type == WifiConfiguration.KeyMgmt.NONE) {  //明文密码
			config.wepKeys[0] = "";
			config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
			config.wepTxKeyIndex = 0;
		} else {  //WPA加密或者WPA2加密
			config.preSharedKey = "\"" + password + "\"";
			config.hiddenSSID = true;
			config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
			config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
			config.allowedKeyManagement.set(type);
			config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
			config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
			config.status = WifiConfiguration.Status.ENABLED;
		}
		return config;
	}


若要断开当前的wifi连接,则既可调用disableNetwork方法,也可调用disconnect方法。disconnect与disableNetwork的区别在于:disableNetwork不但断开连接,并且此后也不会自动重连;而disconnect只是断开本次连接,不会阻止将来的自动重连。


反射reflect

Android因为自身在不断更新升级,同时新技术也是层出不穷,所以并没有把所有的公共方法开放出来。如果我们查看Android的sdk源码,会发现少数函数被标记了hide,表示该函数虽然是public但尚未正式开放,可能是不稳定或者有待完善。可是有时我们又确实需要调用这些隐藏方法,就得通过java的反射机制来间接实现。反射机制指的是在运行过程中,程序对于任意一个类,都知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,而不被hide标记所束缚。


关于反射机制的原理说来话长,我们还是直接说说它的实际应用。首先获取目标类的Class对象,可通过调用对象的getClass方法或者调用Class.forName方法;其次调用该Class对象的getMethod方法,这里需要指定将要访问的方法名、方法参数(先传入参数的类型)等等;再次调用Method的invoke方法,即输入Class对象,以及各参数的具体取值;最后获取invoke的返回值,也就是方法调用的返回结果。


下面是实际开发中运用反射的两个代码例子:
1、开关个人热点
      Method method = wifiMgr.getClass().getMethod(
              "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
      Boolean result = (Boolean) method.invoke(wifiMgr, apConfig, true);
2、获取手机序列号
			Class<?> c = Class.forName("android.os.SystemProperties");
			Method get = c.getMethod("get", String.class);
			String serial = (String) get.invoke(c, "ro.serialno");


如果大家留心,可能发现前面的一些博文已经运用了反射机制,具体说明如下:
1、SignalStrength类获取LTE信号的相关方法,如getLteSignalStrength、getLteRsrp、getLteRsrq等等,参见《 Android开发笔记(四十六)手机相关事件
2、TelephonyManager类获取网络大类与名称的相关方法,如getNetworkClass和getNetworkTypeName,参见《 Android开发笔记(五十五)手机设备基本操作
3、ConnectivityManager类数据连接的相关方法,如getMobileDataEnabled和setMobileDataEnabled,参见《 Android开发笔记(五十五)手机设备基本操作
4、WifiManager类管理热点的相关方法,如setWifiApEnabled、getWifiApState、getWifiApConfiguration等等,参见《 Android开发笔记(六十)网络的检测与连接
5、StorageManager类管理存储的相关方法,如getVolumePaths等等,参见《 Android开发笔记(七十九)资源与权限校验


个人热点

Android支持把手机变成一个wifi热点,其他手机可接入该手机的wifi,从而共享服务端手机的数据流量。下面是WifiManager中与热点相关的方法(注意这些方法都是隐藏的,得通过反射机制来调用):
setWifiApEnabled : 开关热点。true表示开启,false表示关闭。
getWifiApState : WIFI_AP_STATE_DISABLED表示已断开,WIFI_AP_STATE_DISABLING表示正在断开,WIFI_AP_STATE_ENABLED表示已连接,WIFI_AP_STATE_ENABLING表示正在连接,WIFI_AP_STATE_FAILED表示开关失败。
isWifiApEnabled : 判断热点是否启用。只有已连接状态才返回true,其余都返回false。
getWifiApConfiguration : 获取热点的配置信息。
setWifiApConfiguration : 设置热点的配置信息。


因为热点管理本身就不是很完善,所以还存在一些目前无法解决的问题。下面是热点编码的几个注意事项:
1、wifi和热点不能同时打开,所以打开热点的时候需要关闭wifi。
2、热点的配置信息主要有:热点名称
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值