Android的手机ip代码设置------有图有真相

2018年7月18日 23点热度 0条评论 来源: 林尚辉

 首先得说,这个用代码设置手机ip的功能并不常用,只适用于特殊场景需求,例如app刷下载量,不断地更换手机ip来下载应用市场的公司要的应用。

    当然我又不得不吐槽各大应用厂商和谷歌7.0系统,现在的手机系统升级权限各种限制,导致对于系统有些敏感的功能代码,不一定可以用。

 

接下来讲讲我的代码,亲测可以用,在Android5.1系统一下都可以用。反正刷手机下载量的话,并不要求全手机系统兼容。

有图有真相,真实可用。

 

说什么都没用,代码最重要:

SetIpManager.java
package lsh.com.blogipset.iputil;

import android.content.ContentResolver;
import android.content.Context;
import android.net.DhcpInfo;
import android.net.LinkAddress;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;

import java.lang.reflect.Constructor;
import java.net.InetAddress;
import java.util.List;

import static android.content.Context.WIFI_SERVICE;


public class SetIpManager {
    private Context mContext;
    public SetIpManager(Context context) {
        mContext = context;
    }



    public String getIpStr(){
        WifiManager wifiManager = (WifiManager)mContext.getSystemService(WIFI_SERVICE);
        WifiInfo w=wifiManager.getConnectionInfo();
        return intToIp(w.getIpAddress());
    }
    public String intToIp(int ipAddress) {
        return ((ipAddress & 0xff) + "." + (ipAddress >> 8 & 0xff) + "."
                + (ipAddress >> 16 & 0xff) + "." + (ipAddress >> 24 & 0xff));

    }
    private int netmaskIpL;
    public String getWifiSetting(){
        WifiManager wifiManager = (WifiManager) mContext.getSystemService(WIFI_SERVICE);
        DhcpInfo dhcpInfo=wifiManager.getDhcpInfo();
        netmaskIpL=dhcpInfo.netmask;
        if(dhcpInfo.leaseDuration==0){
            return "StaticIP";
        }else{
            return "DHCP";
        }
    }
//    /**
//     * 网关 。
//     *
//     * @param ip
//     * @return
//     */
//    public String long2ip(long ip) {
//        StringBuffer sb = new StringBuffer();
//        sb.append(String.valueOf((int) (ip & 0xff)));
//        sb.append('.');
//        sb.append(String.valueOf((int) ((ip >> 8) & 0xff)));
//        sb.append('.');
//        sb.append(String.valueOf((int) ((ip >> 16) & 0xff)));
//        sb.append('.');
//        sb.append(String.valueOf((int) ((ip >> 24) & 0xff)));
//        return sb.toString();
//    }
//
//    public String intToIp(int ipAddress) {
//        return ((ipAddress & 0xff) + "." + (ipAddress >> 8 & 0xff) + "."
//                + (ipAddress >> 16 & 0xff) + "." + (ipAddress >> 24 & 0xff));
//    }

    /**
     * 设置静态ip地址的方法
     */
    public boolean setIpWithTfiStaticIp(boolean dhcp, String ip, int prefix, String dns1, String gateway) {
        WifiManager wifiManager = (WifiManager) mContext.getSystemService(WIFI_SERVICE);
        boolean flag=false;
        if (!wifiManager.isWifiEnabled()) {
            // wifi is disabled
            return flag;
        }
        // get the current wifi configuration
        WifiConfiguration wifiConfig = null;
        WifiInfo connectionInfo = wifiManager.getConnectionInfo();
        List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
        if (configuredNetworks != null) {
            for (WifiConfiguration conf : configuredNetworks) {
                if (conf.networkId == connectionInfo.getNetworkId()) {
                    wifiConfig = conf;
                    break;
                }
            }
        }
        if (wifiConfig == null) {
            // wifi is not connected
            return flag;
        }
        if (Build.VERSION.SDK_INT < 11) { // 如果是android2.x版本的话
            ContentResolver ctRes = mContext.getContentResolver();
            Settings.System.putInt(ctRes,
                    Settings.System.WIFI_USE_STATIC_IP, 1);
            Settings.System.putString(ctRes,
                    Settings.System.WIFI_STATIC_IP, ip);
            flag=true;
            return flag;
        } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { // 如果是android3.x版本及以上的话
            try {
                IPSetUtils.setIpAssignment("STATIC", wifiConfig);
                IPSetUtils.setIpAddress(InetAddress.getByName(ip), prefix, wifiConfig);
                IPSetUtils.setGateway(InetAddress.getByName(gateway), wifiConfig);
                IPSetUtils.setDNS(InetAddress.getByName(dns1), wifiConfig);
                int netId = wifiManager.updateNetwork(wifiConfig);
                boolean result =  netId!= -1; //apply the setting
                if(result){
                    boolean isDisconnected =  wifiManager.disconnect();
                    boolean configSaved = wifiManager.saveConfiguration(); //Save it
                    boolean isEnabled = wifiManager.enableNetwork(wifiConfig.networkId, true);
                    // reconnect with the new static IP
                    boolean isReconnected = wifiManager.reconnect();
                }
             /*   wifiManager.updateNetwork(wifiConfig); // apply the setting
                wifiManager.saveConfiguration(); //Save it*/
                System.out.println("静态ip设置成功!");
                flag=true;
                return flag;
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("静态ip设置失败!");
                flag=false;
                return flag;
            }
        } else {//如果是android5.x版本及以上的话
            try {
                Class<?> ipAssignment = wifiConfig.getClass().getMethod("getIpAssignment").invoke(wifiConfig).getClass();
                Object staticConf = wifiConfig.getClass().getMethod("getStaticIpConfiguration").invoke(wifiConfig);
                if (dhcp) {
                    wifiConfig.getClass().getMethod("setIpAssignment", ipAssignment).invoke(wifiConfig, Enum.valueOf((Class<Enum>) ipAssignment, "DHCP"));
                    if (staticConf != null) {
                        staticConf.getClass().getMethod("clear").invoke(staticConf);
                    }
                } else {
                    wifiConfig.getClass().getMethod("setIpAssignment", ipAssignment).invoke(wifiConfig, Enum.valueOf((Class<Enum>) ipAssignment, "STATIC"));
                    if (staticConf == null) {
                        Class<?> staticConfigClass = Class.forName("android.net.StaticIpConfiguration");
                        staticConf = staticConfigClass.newInstance();
                    }
                    // STATIC IP AND MASK PREFIX
                    Constructor<?> laConstructor = LinkAddress.class.getConstructor(InetAddress.class, int.class);
                    LinkAddress linkAddress = (LinkAddress) laConstructor.newInstance(
                            InetAddress.getByName(ip),
                            prefix);
                    staticConf.getClass().getField("ipAddress").set(staticConf, linkAddress);
                    // GATEWAY
                    staticConf.getClass().getField("gateway").set(staticConf, InetAddress.getByName(gateway));
                    // DNS
                    List<InetAddress> dnsServers = (List<InetAddress>) staticConf.getClass().getField("dnsServers").get(staticConf);
                    dnsServers.clear();
                    dnsServers.add(InetAddress.getByName(dns1));
//                    dnsServers.add(InetAddress.getByName(Constant.dns2)); // Google DNS as DNS2 for safety
                    // apply the new static configuration
                    wifiConfig.getClass().getMethod("setStaticIpConfiguration", staticConf.getClass()).invoke(wifiConfig, staticConf);
                }

                // apply the configuration change
                boolean result = wifiManager.updateNetwork(wifiConfig) != -1; //apply the setting

                if (result) result = wifiManager.saveConfiguration(); //Save it
                if (result) wifiManager.reassociate(); // reconnect with the new static IP

                int netId = wifiManager.addNetwork(wifiConfig);
                wifiManager.disableNetwork(netId);
                flag  = wifiManager.enableNetwork(netId, true);


            } catch (Exception e) {
                e.printStackTrace();
                flag=false;
            }

        }
        return flag;
    }





}

IPSetUtils.java
package lsh.com.blogipset.iputil;

import android.net.wifi.WifiConfiguration;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.util.ArrayList;

public class IPSetUtils {
    public static void setIpAssignment(String assign, WifiConfiguration wifiConf)
            throws SecurityException, IllegalArgumentException,
            NoSuchFieldException, IllegalAccessException {
        setEnumField(wifiConf, assign, "ipAssignment");
    }

    public static void setEnumField(Object obj, String value, String name)
            throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Field f = obj.getClass().getField(name);
        f.set(obj, Enum.valueOf((Class<Enum>) f.getType(), value));
    }
    public static void setIpAddress(InetAddress addr, int prefixLength,
                                     WifiConfiguration wifiConf) throws SecurityException,
            IllegalArgumentException, NoSuchFieldException,
            IllegalAccessException, NoSuchMethodException,
            ClassNotFoundException, InstantiationException,
            InvocationTargetException {
        Object linkProperties = getField(wifiConf, "linkProperties");
        if (linkProperties == null)
            return;
        Class<?> laClass = Class.forName("android.net.LinkAddress");
        Constructor<?> laConstructor = laClass.getConstructor(new Class[]{

                InetAddress.class, int.class});
        Object linkAddress = laConstructor.newInstance(addr, prefixLength);
        ArrayList<Object> mLinkAddresses = (ArrayList<Object>) getDeclaredField(
                linkProperties, "mLinkAddresses");
        mLinkAddresses.clear();
        mLinkAddresses.add(linkAddress);
    }

    private static Object getField(Object obj, String name)
            throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Field f = obj.getClass().getField(name);
        Object out = f.get(obj);
        return out;
    }

    private static Object getDeclaredField(Object obj, String name)
            throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Field f = obj.getClass().getDeclaredField(name);
        f.setAccessible(true);
        Object out = f.get(obj);
        return out;
    }
    public static void setGateway(InetAddress gateway, WifiConfiguration wifiConf)
            throws SecurityException,
            IllegalArgumentException, NoSuchFieldException,
            IllegalAccessException, ClassNotFoundException,
            NoSuchMethodException, InstantiationException,
            InvocationTargetException {
        Object linkProperties = getField(wifiConf, "linkProperties");
        if (linkProperties == null)
            return;
        if (android.os.Build.VERSION.SDK_INT >= 14) { // android4.x版本
            Class<?> routeInfoClass = Class.forName("android.net.RouteInfo");
            Constructor<?> routeInfoConstructor = routeInfoClass
                    .getConstructor(new Class[]{InetAddress.class});
            Object routeInfo = routeInfoConstructor.newInstance(gateway);
            ArrayList<Object> mRoutes = (ArrayList<Object>) getDeclaredField(

                    linkProperties, "mRoutes");
            mRoutes.clear();
            mRoutes.add(routeInfo);
        } else { // android3.x版本
            ArrayList<InetAddress> mGateways = (ArrayList<InetAddress>) getDeclaredField(

                    linkProperties, "mGateways");
            //    mGateways.clear();
            mGateways.add(gateway);

        }
    }


    public static void setDNS(InetAddress dns, WifiConfiguration wifiConf)

            throws SecurityException, IllegalArgumentException,

            NoSuchFieldException, IllegalAccessException {

        Object linkProperties = getField(wifiConf, "linkProperties");
        if (linkProperties == null)
            return;
        ArrayList<InetAddress> mDnses = (ArrayList<InetAddress>)

                getDeclaredField(linkProperties, "mDnses");
        mDnses.clear(); // 清除原有DNS设置(如果只想增加,不想清除,词句可省略)
        mDnses.add(dns);
        //增加新的DNS
    }
}
MainActivity
package lsh.com.blogipset;

import android.net.wifi.WifiConfiguration;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.net.InetAddress;
import java.net.UnknownHostException;

import lsh.com.blogipset.iputil.SetIpManager;
import lsh.com.blogipset.iputil.android7ip.IPSettings;

public class MainActivity extends AppCompatActivity {
    private Button mButton, mButton2, mButton3, mButton4, mButton5;
    private EditText mEtTextIp,mEtTextGateWay;
    private SetIpManager IpConfig;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IpConfig = new SetIpManager(MainActivity.this);//封装,获取ip设置对象
        initBindView();
        initOnclick();
    }

    private void initOnclick() {
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String ipText=mEtTextIp.getText().toString().trim();
                String gateWayText=mEtTextGateWay.getText().toString().trim();
                //IP 网络前缀长度24 DNS1域名1 网关
                Boolean isSetSuccess = IpConfig.setIpWithTfiStaticIp(false, ipText, 24, "255.255.255.0", gateWayText);
                Toast.makeText(MainActivity.this, "" + isSetSuccess, Toast.LENGTH_SHORT).show();

            }
        });
        mButton2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //IP 网络前缀长度24 DNS1域名1 网关
                String ipText=mEtTextIp.getText().toString().trim();
                String gateWayText=mEtTextGateWay.getText().toString().trim();
                Boolean isSetSuccess = IpConfig.setIpWithTfiStaticIp(true, ipText, 24, "255.255.255.0", gateWayText);
                Toast.makeText(MainActivity.this, "" + isSetSuccess, Toast.LENGTH_SHORT).show();

            }
        });
        mButton3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String ip = IpConfig.getIpStr();
                Toast.makeText(MainActivity.this, ip, Toast.LENGTH_SHORT).show();
            }
        });
        mButton4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, IpConfig.getWifiSetting(), Toast.LENGTH_SHORT).show();
            }
        });


        conf = new WifiConfiguration();
        mButton5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //不一定能用,Android6.0后的有些系统厂商对这个敏感功能进行限制
                String IP_ADDRESS = "192.168.0.193";
                String GATEWAY = "192.168.0.1";
                int PREFIX_LENGTH = 24;
                InetAddress[] dns_servers = new InetAddress[0];
                try {
                    dns_servers = new InetAddress[]{InetAddress.getByName("8.8.8.8"), InetAddress.getByName("8.8.4.4")};
                    conf = IPSettings.setStaticIpConfiguration(conf,InetAddress.getByName(IP_ADDRESS),PREFIX_LENGTH,InetAddress.getByName(GATEWAY),dns_servers);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    WifiConfiguration conf;//不一定能用,Android6.0后的有些系统厂商对这个敏感功能进行限制
    private void initBindView() {
        mButton = (Button) findViewById(R.id.bt_change_ip1);
        mButton2 = (Button) findViewById(R.id.bt_change_ip2);
        mButton3 = (Button) findViewById(R.id.bt_change_ip3);
        mButton4 = (Button) findViewById(R.id.bt_change_ip4);
        mButton5 = (Button) findViewById(R.id.bt_change_ip5);
        mEtTextIp = (EditText) findViewById(R.id.ip_et);
        mEtTextGateWay = (EditText) findViewById(R.id.gateway_et);
    }

}

androidmainfest.xml权限问题:

    <!--系统权限用于定制设备-->
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
    <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />

    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <!-- wifi控制和状态权限 -->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!-- 网络状态改变的权限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <!-- 6.0以上打开蓝牙和wifi最好加上定位权限,获取wifi列表要用 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- 获取IP地址 -->
    <uses-permission android:name="android.permission.INTERNET"/>

系统权限在Android5.1版本前的设备不需要就可以直接用, 至于我为什么把系统权限也写入,是因为虽然爆红线但是不影响编译,主要是如果将app编译成系统app后就可以无限制在Android7.0后续版本正常使用。系统权限可以删除,不影响。

 

最后项目下载地址

GitHub下载地址

 

 

有用请点赞,谢谢各位大侠了!!

 

 

    原文作者:林尚辉
    原文地址: https://blog.csdn.net/insist_hui/article/details/81084068
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。