首先说下需求:要求能实时监听网络状态发生改变,并显示出来
监听网络变化,可通过监听系统广播 来实现,android系统网络发生改变时,会发广播,通过监听这个广播,即可知道网络是否发生改变,再去获取网络状态
我的想法是把这个监听放在一个自定义控件中,
具体实现:
第一步:先准备一个工具类,用来显示IP信息相关的(见后面的代码)
package com.ytmfdw.routecrack.utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
/**
* IP地址工具类
*/
public class IPUtils {
/**
* 获取IP地 址
*
* @return
*/
public static String getIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface
.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf
.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()
&& inetAddress instanceof Inet4Address) {
// if (!inetAddress.isLoopbackAddress() && inetAddress
// instanceof Inet6Address) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取WIFI的ip地址
*
* @param context
* @return
*/
public static String getWifiIp(Context context) {
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
// DhcpInfo dhcp = wifi.getDhcpInfo();
// String mask = getIpStringByint(dhcp.netmask);
// String gateWay = getIpStringByint(dhcp.gateway);
// L.d("ytmfdw", "掩码:" + mask);
// L.d("ytmfdw", "网关:" + gateWay);
// 获得IP地址的方法一:
int ipAddress = info.getIpAddress();
String ipString = "";
ipString = getIpStringByint(ipAddress);
return ipString;
}
/**
* 获取网关
*
* @param context
* @return
*/
public static String getGateWay(Context context) {
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
DhcpInfo dhcp = wifi.getDhcpInfo();
return getIpStringByint(dhcp.gateway);
}
/**
* 获取掩码
*
* @param context
* @return
*/
public static String getNetMask(Context context) {
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
DhcpInfo dhcp = wifi.getDhcpInfo();
return getIpStringByint(dhcp.netmask);
}
/**
* 获取MAC地址
*
* @param context
* @return
*/
public String getLocalMacAddress(Context context) {
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
return info.getMacAddress();
}
/**
* 获取当前WIFI状态
*
* @param context
* @return
*/
public static String getCurrentNetType(Context context) {
String type = "";
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info == null) {
type = "null";
} else if (info.getType() == ConnectivityManager.TYPE_WIFI) {
type = "wifi";
} else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
int subType = info.getSubtype();
if (subType == TelephonyManager.NETWORK_TYPE_CDMA || subType == TelephonyManager.NETWORK_TYPE_GPRS
|| subType == TelephonyManager.NETWORK_TYPE_EDGE) {
type = "2g";
} else if (subType == TelephonyManager.NETWORK_TYPE_UMTS || subType == TelephonyManager.NETWORK_TYPE_HSDPA
|| subType == TelephonyManager.NETWORK_TYPE_EVDO_A || subType == TelephonyManager.NETWORK_TYPE_EVDO_0
|| subType == TelephonyManager.NETWORK_TYPE_EVDO_B) {
type = "3g";
} else if (subType == TelephonyManager.NETWORK_TYPE_LTE) {// LTE是3g到4g的过渡,是3.9G的全球标准
type = "4g";
}
}
return type;
}
/**
* 把ip整形数据转换点分十进制
*
* @param ipAddress
* @return
*/
public static String getIpStringByint(int ipAddress) {
String ipString = "";
if (ipAddress != 0) {
ipString = ((ipAddress & 0xff) + "." + (ipAddress >> 8 & 0xff) + "."
+ (ipAddress >> 16 & 0xff) + "." + (ipAddress >> 24 & 0xff));
}
// ipString = Formatter.formatIpAddress(ipAddress);
return ipString;
}
}
第二步:自定义一个View,继承自TextView,我只是想以文字方式显示出来,当然也可以继承自ImageView或View
第三步:在该类中,定义一个广播接收器,接收网络状态发生改变广播,当有变化时,重新获取网络信息,并重新设置界面
class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
getNetInfo();
setText(text);
}
}
}
其中,getNetInfo方法为获取网络信息方法:
private void getNetInfo() {
mConnectivityManager = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
netInfo = mConnectivityManager.getActiveNetworkInfo(); // 获取网络状态信息
if (netInfo != null && netInfo.isAvailable()) {//网络状态不能为空,并且是有效的
String name = netInfo.getTypeName();//得到网络名称。如:wifi
StringBuilder sb = new StringBuilder();
switch (netInfo.getType()) {//获取网络状态类型 int值
case ConnectivityManager.TYPE_WIFI:
state = STATE_WIFI;
sb.append("WiFi网络").append("\n");
sb.append("IP:").append(IPUtils.getWifiIp(getContext())).append("\n")
.append("Mask:").append(IPUtils.getNetMask(getContext())).append("\n")
.append("GateWay:").append(IPUtils.getGateWay(getContext()));
text = sb.toString();
// Toast.makeText(context, "WiFi网络!", Toast.LENGTH_LONG).show();
break;
case ConnectivityManager.TYPE_MOBILE:
// Toast.makeText(context, "移动网络!", Toast.LENGTH_LONG).show();
state = STATE_MOBILE;
sb.append("手机网络").append("\n");
sb.append("IP:").append(IPUtils.getIpAddress()).append("\n")
.append("Mask:").append(IPUtils.getNetMask(getContext())).append("\n")
.append("GateWay:").append(IPUtils.getGateWay(getContext()));
text = sb.toString();
break;
case ConnectivityManager.TYPE_ETHERNET:
// Toast.makeText(context, "以太网有线网络!", Toast.LENGTH_LONG).show();
state = STATE_ETHERNET;
sb.append("有线网络").append("\n");
sb.append("IP:").append(IPUtils.getWifiIp(getContext())).append("\n")
.append("Mask:").append(IPUtils.getNetMask(getContext())).append("\n")
.append("GateWay:").append(IPUtils.getGateWay(getContext()));
text = sb.toString();
break;
}
} else {
// Toast.makeText(context, "无网络状态!", Toast.LENGTH_LONG).show();
text = "无网络";
state = STATE_NONE;
}
//通知网络改变
if (this.linstener != null) {
this.linstener.onChange(state);
}
}
第四步:重写onAttachedToWindow,该方法在View被加载到窗体中时触发,在该方法体中,注册广播接收器
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
//注册广播
receiver = new MyReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
getContext().registerReceiver(receiver, filter);
}
第五步:重写onDetachedFromWindow,这个方法在View从窗体中分离时触发 ,与onAttachedToWindow是一对,在该方法中,反注册广播接收器
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (receiver != null) {
getContext().unregisterReceiver(receiver);
}
}
完整的WIFIView代码:
package com.ytmfdw.routecrack.widget;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.AttributeSet;
import android.widget.TextView;
import com.ytmfdw.routecrack.utils.IPUtils;
/**
* 自定义监听网络状态改变View
*/
public class WIFIView extends TextView {
public interface NetworkChange {
public void onChange(int state);
}
private ConnectivityManager mConnectivityManager;
private NetworkInfo netInfo;
NetworkChange linstener;
/**
* 无网络
*/
public static final int STATE_NONE = 0;
/**
* WIFI状态
*/
public static final int STATE_WIFI = 1;
/**
* 手机网络状态
*/
public static final int STATE_MOBILE = 2;
/**
* 有线网络状态
*/
public static final int STATE_ETHERNET = 3;
/**
* 当前状态
*/
private int state = STATE_NONE;
MyReceiver receiver;
String text = "无网络状态";
public WIFIView(Context context) {
this(context, null);
}
public WIFIView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
/**
* 设置网络状态改变监听
*
* @param change
*/
public void setOnNetworkChange(NetworkChange change) {
this.linstener = change;
}
private void init() {
getNetInfo();
setText(text);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
//注册广播
receiver = new MyReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
getContext().registerReceiver(receiver, filter);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (receiver != null) {
getContext().unregisterReceiver(receiver);
}
}
public int getState() {
return state;
}
class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
getNetInfo();
setText(text);
}
}
}
private void getNetInfo() {
mConnectivityManager = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
netInfo = mConnectivityManager.getActiveNetworkInfo(); // 获取网络状态信息
if (netInfo != null && netInfo.isAvailable()) {//网络状态不能为空,并且是有效的
String name = netInfo.getTypeName();//得到网络名称。如:wifi
StringBuilder sb = new StringBuilder();
switch (netInfo.getType()) {//获取网络状态类型 int值
case ConnectivityManager.TYPE_WIFI:
state = STATE_WIFI;
sb.append("WiFi网络").append("\n");
sb.append("IP:").append(IPUtils.getWifiIp(getContext())).append("\n")
.append("Mask:").append(IPUtils.getNetMask(getContext())).append("\n")
.append("GateWay:").append(IPUtils.getGateWay(getContext()));
text = sb.toString();
// Toast.makeText(context, "WiFi网络!", Toast.LENGTH_LONG).show();
break;
case ConnectivityManager.TYPE_MOBILE:
// Toast.makeText(context, "移动网络!", Toast.LENGTH_LONG).show();
state = STATE_MOBILE;
sb.append("手机网络").append("\n");
sb.append("IP:").append(IPUtils.getIpAddress()).append("\n")
.append("Mask:").append(IPUtils.getNetMask(getContext())).append("\n")
.append("GateWay:").append(IPUtils.getGateWay(getContext()));
text = sb.toString();
break;
case ConnectivityManager.TYPE_ETHERNET:
// Toast.makeText(context, "以太网有线网络!", Toast.LENGTH_LONG).show();
state = STATE_ETHERNET;
sb.append("有线网络").append("\n");
sb.append("IP:").append(IPUtils.getWifiIp(getContext())).append("\n")
.append("Mask:").append(IPUtils.getNetMask(getContext())).append("\n")
.append("GateWay:").append(IPUtils.getGateWay(getContext()));
text = sb.toString();
break;
}
} else {
// Toast.makeText(context, "无网络状态!", Toast.LENGTH_LONG).show();
text = "无网络";
state = STATE_NONE;
}
//通知网络改变
if (this.linstener != null) {
this.linstener.onChange(state);
}
}
}
其中,定义了一个接口:NetworkChange,可在Activity中对WIFIView设置监听,通过接口回调方式实现
完整代码:点击我下载