自定义控件监听网络改变

首先说下需求:要求能实时监听网络状态发生改变,并显示出来

监听网络变化,可通过监听系统广播 来实现,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设置监听,通过接口回调方式实现

完整代码:点击我下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ytmfdw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值