自定义控件监听网络改变

来源:互联网 发布:阿里云快还是腾讯云快 编辑:程序博客网 时间: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
原创粉丝点击