自定义控件监听网络改变
来源:互联网 发布:阿里云快还是腾讯云快 编辑:程序博客网 时间:2024/06/06 03:19
首先说下需求:要求能实时监听网络状态发生改变,并显示出来
监听网络变化,可通过监听系统广播 来实现,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设置监听,通过接口回调方式实现
完整代码:点击我下载
0 0
- 自定义控件监听网络改变
- Android 网络改变监听
- 监听网络状态改变
- AF监听网络改变
- 自定义控件旋转时改变内部布局--监听UIView size的改变
- 监听控件值的改变
- 监听android控件焦点改变
- 监听网络状态的改变
- 监听网络状态的改变
- 监听滑动条控件Slider值改变
- android EditTex 控件文本内容改变监听
- 自定义控件三秒改变改变颜色
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- android 监听网络连接状态的改变
- Button的背景透明度或者颜色的设置
- 堆和栈的区别(转过无数次的文章)
- h5混合APP开发
- MySQL 5.7 Reference Manual Chapter 13 Functions and Operators 参考手册第十三章函数与操作符内容总结
- This application's application-identifier entitlement does not match that of the installed applicati
- 自定义控件监听网络改变
- 安卓通过注解+反射简单实现代替findViewById方法
- PCA(主元分析)的数学原理
- Colored Sticks(欧拉回路+字典树+并查集)
- skearn.cluster.AffiinityPropagation
- J2EE学习笔记(三)
- LeetCode 27 Remove Element题解
- CLLocationManager定位坐标不准确问题以及WGS_84转GCJ_02坐标位置纠错的方法
- Pandas常用笔记