1. 程式人生 > >關於Android 5.0 、6.0 、 7.0程式碼設定WIFI連線方式為靜態IP或DHCP的方法及注意事項

關於Android 5.0 、6.0 、 7.0程式碼設定WIFI連線方式為靜態IP或DHCP的方法及注意事項

注意:Android6.0以上app不具備刪除,修改WiFi許可權。

如果是自己APP通過程式碼連線的,(如果系統本來就記住了該WIFI,APP裡通過程式碼在連線一次不算),需要許可權

<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
可以刪除該WiFi 和修改。

在Android6.0以上,呼叫以下方法,如果返回-1 和false  著說明沒有許可權或者該 WIFI建立者不是本app(每一個WiFi記錄下回記錄WiFi建立者的APP id)。

mwifiManager.updateNetwork(config);
mwifiManager.removeNetwork(tempConfig.networkId);

如果想要在Android6.0程式碼設定WIFI連線方式為靜態IP,就得提示使用者,去WiFi設定裡面取消儲存(或忘記、刪除)該WiFi,然後使用者在APP裡選擇WIFI,輸入密碼,程式碼連線WiFi,然後通過反射呼叫系統隱藏方法更改連線方式。

注意:WiFi由靜態IP改為DHCP或由DHCP改為靜態IP需要重啟WIFI(直接在手機設定裡面改連線方式,WIFI也是會斷開在重新連線的),既呼叫以下方法:

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

下面是設定WiFi連線方式的方法類:

在5.0系統上直接呼叫就可以修改。(5.1的裝置測試可用)

在6.0以上如果返回false,應該就是應為該WIFI不是該APP建立的,沒有修改許可權。(APP內連線的WIFI 測試方法可用)

因為沒有5.0以下的手機,所以沒有測試5.0系統以下的方法。

package com.jisai.wifiip;
import android.content.ContentResolver;
import android.content.Context;
import android.net.LinkAddress; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.hotspot2.PasspointConfiguration; import android.os.Build; import android.provider.Settings; import android.util.Log; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.net.InetAddress; import java.util.ArrayList; import java.util.List; /** * Created by Administrator on 2017/12/4 0004. */ public class StaticIpUtil { Context mContext; public StaticIpUtil(Context context) { mContext = context; } // public void getNetworkInformation() { // WifiManager mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); // int ipAddress = mWifiManager.getConnectionInfo().getIpAddress(); // Constant.IP = intToIp(ipAddress); // long getwayIpS = mWifiManager.getDhcpInfo().gateway; // Constant.gateway = long2ip(getwayIpS); // // 注意要加\\,要不出不來,yeah // String[] IPS = Constant.IP.split("\\."); // Constant.IP = IPS[0] + "." + IPS[1] + "." + IPS[2] + "." + Constant.IPLast; // Constant.isConnectSocket = IPS[0] + "." + IPS[1] + "." + IPS[2] + "." + Constant.IPLast; // String zeroIP = "0" + "." + "0" + "." + "0" + "." + Constant.IPLast; // String equalIP = IPS[0] + "." + IPS[1] + "." + IPS[2] + "." + IPS[3]; // if (!Constant.IP.equals(zeroIP) && !Constant.IP.equals(equalIP)) { // setIpWithTfiStaticIp(false, Constant.IP, Constant.prefix, Constant.dns1, Constant.gateway); // } // } /** * 閘道器 。 * * @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(Context.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, "192.168.0.202"); flag=true; return flag; } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { // 如果是android3.x版本及以上的話 try { setIpAssignment("STATIC", wifiConfig); setIpAddress(InetAddress.getByName(ip), prefix, wifiConfig); setGateway(InetAddress.getByName(gateway), wifiConfig); 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); Log.e("wifiConfig.getClass()",wifiConfig.getClass().toString()); if (dhcp) { wifiConfig.getClass().getMethod("setIpAssignment", ipAssignment).invoke(wifiConfig, Enum.valueOf((Class<Enum>) ipAssignment, "DHCP")); if (staticConf != null) { staticConf.getClass().getMethod("clear").invoke(staticConf); Log.e("自動分配模式","staticConf!=null"); }else{ Log.e("自動分配模式","staticConf==null"); } } else { wifiConfig.getClass().getMethod("setIpAssignment", ipAssignment).invoke(wifiConfig, Enum.valueOf((Class<Enum>) ipAssignment, "STATIC")); if (staticConf == null) { Log.e("靜態IP模式","staticConf==null"); Class<?> staticConfigClass = Class.forName("android.net.StaticIpConfiguration"); staticConf = staticConfigClass.newInstance(); if (staticConf == null) { Log.e("靜態IP模式","staticConf還是==null"); } }else{ Log.e("靜態IP模式","staticConf!=null"); } // 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 Log.e("result",result+""); if (result) result = wifiManager.saveConfiguration(); //Save it Log.e("saveConfiguration",result+""); if (result) wifiManager.reassociate(); // reconnect with the new static IP Log.e("reassociate",result+""); int netId = wifiManager.addNetwork(wifiConfig); wifiManager.disableNetwork(netId); flag = wifiManager.enableNetwork(netId, true); Log.e("netId",netId+""); // if(b){ // Toast.makeText(getApplication(),"連線成功!",Toast.LENGTH_SHORT).show(); // }else{ // Toast.makeText(getApplication(),"連線失敗!請確定伺服器熱點是否開啟!",Toast.LENGTH_SHORT).show(); // // } // flag=true; } catch (Exception e) { e.printStackTrace(); flag=false; } } return flag; } private static void setIpAssignment(String assign, WifiConfiguration wifiConf) throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException { setEnumField(wifiConf, assign, "ipAssignment"); } private 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; } private 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)); } private 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); } } private 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 } }

呼叫方法

case R.id.aaa:

    //IP 網路字首長度24 DNS1域名1 閘道器
Boolean b= s.setIpWithTfiStaticIp(false,"192.168.1.123",24,"255.255.255.0","192.168.1.1");
Toast.makeText(MainActivity.this,""+b,Toast.LENGTH_SHORT).show();
    break;
case R.id.aaa2:
    //IP 網路字首長度24 DNS1域名1 閘道器
Boolean c=  s.setIpWithTfiStaticIp(true,"192.168.1.123",24,"255.255.255.0","192.168.1.1");
Toast.makeText(MainActivity.this,""+c,Toast.LENGTH_SHORT).show();
    break;

程式碼連線WiFi方法:

String ssid =  "wifisocket";
String password = "00000000";
mWifiConfiguration = CreateWifiInfo(ssid, password, 3);
System.out.println("mWifiConfiguration"+mWifiConfiguration);
int wcgID = mwifiManager.addNetwork(mWifiConfiguration);
boolean bbb = mwifiManager.enableNetwork(wcgID, true);
Log.e("wcgID",""+wcgID);
Log.e("b",""+bbb);

public WifiConfiguration CreateWifiInfo(String SSID, String Password,
                                        int Type) {
    WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID+"\"";
WifiConfiguration tempConfig = this.IsExsits(SSID);
    if (tempConfig != null) {

    Boolean c=    mwifiManager.removeNetwork(tempConfig.networkId);
Log.e("建立新的",""+c);
}

    if (Type == 1) // WIFICIPHER_NOPASS
{
        config.wepKeys[0] = "";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
}
    if (Type == 2) // WIFICIPHER_WEP
{
        config.hiddenSSID = true;
config.wepKeys[0] = "\"" + Password + "\"";
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
}
    if (Type == 3) // WIFICIPHER_WPA
{
        config.preSharedKey = "\"" + Password + "\"";
config.hiddenSSID = true;
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
}
    return config;
}

6.0以上設定IP方法(5.0應該也可以用,和上面的方法是一樣的,上面的》=5.X的6.0也可以用)

按鍵呼叫該方法:

case R.id.aaa6:
    try {
        setStaticIpConfiguration(mwifiManager, mWifiConfiguration,
InetAddress.getByName("106.168.0.235"), 24,
InetAddress.getByName("192.168.0.202"),
InetAddress.getAllByName("8.8.8.8"));
} catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
        // TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
        // TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
        // TODO Auto-generated catch block
e.printStackTrace();
}

    break;
@SuppressWarnings("unchecked")
public static void setStaticIpConfiguration(WifiManager manager,
WifiConfiguration config, InetAddress ipAddress, int prefixLength,
InetAddress gateway, InetAddress[] dns)
        throws ClassNotFoundException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, NoSuchFieldException, InstantiationException {
    // First set up IpAssignment to STATIC.
Object ipAssignment = getEnumValue(
            "android.net.IpConfiguration$IpAssignment", "STATIC");
callMethod(config, "setIpAssignment",
            new String[] { "android.net.IpConfiguration$IpAssignment" },
            new Object[] { ipAssignment });
// Then set properties in StaticIpConfiguration.
Object staticIpConfig = newInstance("android.net.StaticIpConfiguration");
Object linkAddress = newInstance("android.net.LinkAddress",
            new Class[] { InetAddress.class, int.class }, new Object[] {
                    ipAddress, prefixLength });
setField(staticIpConfig, "ipAddress", linkAddress);
setField(staticIpConfig, "gateway", gateway);
ArrayList<Object> aa = (ArrayList<Object>) getField(staticIpConfig,
"dnsServers");
aa.clear();
    for (int i = 0; i < dns.length; i++)
        aa.add(dns[i]);
callMethod(config, "setStaticIpConfiguration",
            new String[] { "android.net.StaticIpConfiguration" },
            new Object[] { staticIpConfig });
System.out.println("conconconm" + config);
    int updateNetwork = manager.updateNetwork(config);
    boolean saveConfiguration = manager.saveConfiguration();
System.out.println("updateNetwork" + updateNetwork + saveConfiguration);
System.out.println("ttttttttttt" + "成功");
    int netId = manager.addNetwork(config);
manager.disableNetwork(netId);
    boolean  flag  = manager.enableNetwork(netId, true);
Log.e("netId",netId+"");
Log.e("flag",flag+"");
}



private static Object newInstance(String className)
        throws ClassNotFoundException, InstantiationException,
IllegalAccessException, NoSuchMethodException,
IllegalArgumentException, InvocationTargetException {
    return newInstance(className, new Class[0], new Object[0]);
}



@SuppressWarnings({ "rawtypes", "unchecked" })
private static Object newInstance(String className,
Class[] parameterClasses, Object[] parameterValues)
        throws NoSuchMethodException, InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, ClassNotFoundException {
    Class clz = Class.forName(className);
Constructor constructor = clz.getConstructor(parameterClasses);
    return constructor.newInstance(parameterValues);
}



@SuppressWarnings({ "unchecked", "rawtypes" })
private static Object getEnumValue(String enumClassName, String enumValue)
        throws ClassNotFoundException {
    Class enumClz = (Class) Class.forName(enumClassName);
    return Enum.valueOf(enumClz, enumValue);
}



private static void setField(Object object, String fieldName, Object value)
        throws IllegalAccessException, IllegalArgumentException,
NoSuchFieldException {
    Field field = object.getClass().getDeclaredField(fieldName);
field.set(object, value);
}



private static Object getField(Object object, String fieldName)
        throws IllegalAccessException, IllegalArgumentException,
NoSuchFieldException {
    Field field = object.getClass().getDeclaredField(fieldName);
Object out = field.get(object);
    return out;
}



@SuppressWarnings("rawtypes")
private static void callMethod(Object object, String methodName,
String[] parameterTypes, Object[] parameterValues)
        throws ClassNotFoundException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
NoSuchMethodException {
    Class[] parameterClasses = new Class[parameterTypes.length];
    for (int i = 0; i < parameterTypes.length; i++)
        parameterClasses[i] = Class.forName(parameterTypes[i]);
Method method = object.getClass().getDeclaredMethod(methodName,
parameterClasses);
method.invoke(object, parameterValues);
}


public String intToIp(int ipAddress) {
    return ((ipAddress & 0xff) + "." + (ipAddress >> 8 & 0xff) + "."
+ (ipAddress >> 16 & 0xff) + "." + (ipAddress >> 24 & 0xff));
}
// 直接使用set方法呼叫 可能遇到需要地址轉換方法如下:
public static String int2ip(int ip) {
    StringBuilder sb = new StringBuilder();
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();
}

檢視IP的方法:

case R.id.aaa3:
    WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo w=wifiManager.getConnectionInfo();
String ip=intToIp(w.getIpAddress());
Log.e("IP",ip);
Toast.makeText(MainActivity.this,ip,Toast.LENGTH_SHORT).show();
    break;

檢視連線方式的方法:

public String getWifiSetting(Context context){
    WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);
DhcpInfo dhcpInfo=wifiManager.getDhcpInfo();
netmaskIpL=dhcpInfo.netmask;
    if(dhcpInfo.leaseDuration==0){
        return "StaticIP";
}else{
        return "DHCP";
}
}

package com.jisai.wifiip;
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 android.support.annotation.BoolRes;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;