简单的一个函数实现对wifi设置静态或动态IP地址。
一、需要的权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG"
tools:ignore="ProtectedPermissions" />
可以删除该WiFi 和修改。
二、清单文件需要将shareduserid设置成system。
android:sharedUserId="android.uid.system"
三、具体函数,函数执行条件是wifi开关打开,并且要设置的wifi已经连接成功。
// 定义几种加密方式,一种是WEP,一种是WPA,还有没有密码的情况
public enum WifiCipherType {
WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID
}
/**
* @param context use Application context is better
* @param ipAddress ip address: like 192.168.1.168
* @param mode : STATIC or DHCP, set static or dhcp ip mode
* @param netmask ip mask, like 255.255.255.0
* @param gateway gateway, like 192.168.1.1
* @param dns1 dns 1
* @param dns2 dns 2, if mode=static, then can use "" or null
* @param ssid current has connected wifi ssid
* @param pwd current has connected wifi pwd
* @param wifiCipherType current has connected wifi capabilities
* eg. dhcp mode: setWifiStaticIP(ApplicationContext, "DHCP", "", "", "", "", "", "test", "123456", WifiCipherType.WIFICIPHER_WPA);
* static mode: setWifiStaticIP(ApplicationContext, "STATIC",
* "192.168.1.168", "255.255.255.0",
* "192.168.1.1", "114.114.114.114", "8.8.8.8", "test", "123456", WifiCipherType.WIFICIPHER_WPA);
* for android 9.0
*/
public static boolean setWifiStaticIP(Context context, String mode, String ipAddress, String netmask,
String gateway, String dns1, String dns2,
String ssid, String pwd, WifiCipherType wifiCipherType) {
if (context == null || (!"STATIC".equals(mode) && !"DHCP".equals(mode))
|| TextUtils.isEmpty(ssid) || wifiCipherType == null
|| TextUtils.isEmpty(wifiCipherType.name())) {
Log.d(TAG, " setWifiStaticIP failed, param incorrect context=" + context + ", mode=" + mode);
return false;
}
try {
WifiManager wifiManager = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE));
if ("DHCP".equals(mode)) {
IpConfiguration dhcpConfiguration = new IpConfiguration(IpConfiguration.IpAssignment.DHCP,
IpConfiguration.ProxySettings.NONE, null, null);
dhcpConfiguration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
WifiConfiguration wifiConfiguration = createWifiConfig(ssid, pwd, wifiCipherType, dhcpConfiguration);
// current assignment is DHCP OR STATIC
String assignMent = wifiConfiguration.getIpConfiguration().ipAssignment.name();
Log.d(TAG, " setWifiStaticIP assignMent=" + assignMent + ", mode=" + mode);
wifiManager.setWifiApConfiguration(wifiConfiguration);
// update network
wifiManager.updateNetwork(wifiConfiguration);
// reconnect
int netId = wifiManager.addNetwork(wifiConfiguration);
wifiManager.disableNetwork(netId);
wifiManager.enableNetwork(netId, true);
Log.i(TAG, " setWifiStaticIP dhcp set success");
return true;
}
// set static ip address
IpConfiguration ipConfiguration = getStaticIpConfiguration(ipAddress, netmask, gateway, dns1, dns2);
if (ipConfiguration != null) {
WifiConfiguration wifiConfiguration = createWifiConfig(ssid, pwd, wifiCipherType, ipConfiguration);
wifiManager.setWifiApConfiguration(wifiConfiguration);
// update network
wifiManager.updateNetwork(wifiConfiguration);
// reconnect
int netId = wifiManager.addNetwork(wifiConfiguration);
wifiManager.disableNetwork(netId);
wifiManager.enableNetwork(netId, true);
Log.i(TAG, "setWifiStaticIP set static ip success");
return true;
} else {
Log.w(TAG, "setWifiStaticIP set static ip failed");
return false;
}
} catch (Exception e) {
Log.e(TAG, "setWifiStaticIP e=" + e.getMessage());
}
return false;
}
private static IpConfiguration getStaticIpConfiguration(String ipAddress, String netmask, String gateway, String dns1, String dns2) {
try {
StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
int prefixLength = maskStr2InetMask(netmask);
InetAddress inetAddr = null;
InetAddress gatewayAddr = getIPv4Address(gateway);
InetAddress dnsAddr = getIPv4Address(dns1);
if (TextUtils.isEmpty(ipAddress)) {
inetAddr = getLocalIPAddress();
} else {
String[] ipStr = ipAddress.split("\\.");
byte[] ipBuf = new byte[4];
for (int i = 0; i < 4; i++) {
ipBuf[i] = (byte) (Integer.parseInt(ipStr[i]) & 0xff);
}
try {
inetAddr = InetAddress.getByAddress(ipBuf);
Log.d(TAG, "getStaticIpConfiguration address correct inetAddr=" + inetAddr);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
if (inetAddr == null || inetAddr.getAddress().toString().isEmpty()
|| prefixLength == 0 || gatewayAddr.toString().isEmpty()
|| dnsAddr == null || dnsAddr.toString().isEmpty()) {
Log.d(TAG, " getStaticIpConfiguration address incorrect inetAddr=" + inetAddr);
return null;
}
Class<?> linkAddressClass = null;
linkAddressClass = Class.forName("android.net.LinkAddress");
Class[] cl = new Class[]{InetAddress.class, int.class};
Constructor cons = null;
try {
cons = linkAddressClass.getConstructor(cl);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Object[] x = {inetAddr, prefixLength};
try {
staticIpConfiguration.ipAddress = (LinkAddress) cons.newInstance(x);
Log.d(TAG, " getStaticIpConfiguration staticIpConfiguration.ipAddress=" + staticIpConfiguration.ipAddress);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
staticIpConfiguration.gateway = gatewayAddr;
staticIpConfiguration.dnsServers.add(dnsAddr);
if (!dns2.isEmpty())
staticIpConfiguration.dnsServers.add(getIPv4Address(dns2));
Log.d(TAG, " getStaticIpConfiguration staticIpConfiguration ====" + staticIpConfiguration
+ ", inetAddr=" + inetAddr);
IpConfiguration ipConfiguration = new IpConfiguration(IpConfiguration.IpAssignment.STATIC,
IpConfiguration.ProxySettings.NONE, staticIpConfiguration, null);
ipConfiguration.setIpAssignment(IpConfiguration.IpAssignment.STATIC);
ipConfiguration.setStaticIpConfiguration(staticIpConfiguration);
return ipConfiguration;
} catch (Exception e) {
Log.e(TAG, "getStaticIpConfiguration ERROR=" + e.getMessage());
}
return null;
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2020/07/22补充上述中缺失的函数。
/*
* convert subMask string to prefix length
*/
public static int maskStr2InetMask(String maskStr) {
StringBuffer sb;
String str;
int inetmask = 0;
int count = 0;
/*
* check the subMask format
*/
Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$");
if (pattern.matcher(maskStr).matches() == false) {
Log.e(TAG, "subMask is error");
return 0;
}
String[] ipSegment = maskStr.split("\\.");
for (int n = 0; n < ipSegment.length; n++) {
sb = new StringBuffer(Integer.toBinaryString(Integer.parseInt(ipSegment[n])));
str = sb.reverse().toString();
count = 0;
for (int i = 0; i < str.length(); i++) {
i = str.indexOf("1", i);
if (i == -1)
break;
count++;
}
inetmask += count;
}
return inetmask;
}
public static InetAddress getIPv4Address(String text) {
try {
return NetworkUtils.numericToInetAddress(text);
} catch (IllegalArgumentException | ClassCastException e) {
return null;
}
}
/**
* Get local Ip address.
*/
public static InetAddress getLocalIPAddress() {
Enumeration<NetworkInterface> enumeration = null;
try {
enumeration = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e) {
e.printStackTrace();
}
if (enumeration != null) {
while (enumeration.hasMoreElements()) {
NetworkInterface nif = enumeration.nextElement();
Enumeration<InetAddress> inetAddresses = nif.getInetAddresses();
if (inetAddresses != null) {
while (inetAddresses.hasMoreElements()) {
InetAddress inetAddress = inetAddresses.nextElement();
if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) {
return inetAddress;
}
}
}
}
}
return null;
}
public static WifiConfiguration createWifiConfig(String SSID, String password,
WifiCipherType type,
IpConfiguration ipConfiguration) {
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\"";
config.setIpConfiguration(ipConfiguration);
if (type == WifiCipherType.WIFICIPHER_NOPASS) {
// config.wepKeys[0] = ""; //注意这里
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
// config.wepTxKeyIndex = 0;
}
if (type == WifiCipherType.WIFICIPHER_WEP) {
config.preSharedKey = "\"" + password + "\"";
config.hiddenSSID = true;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
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 == WifiCipherType.WIFICIPHER_WPA) {
config.preSharedKey = "\"" + password + "\"";
config.hiddenSSID = true;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.status = WifiConfiguration.Status.ENABLED;
}
return config;
}
/**
* Ipv4 address check.
*/
private static final Pattern IPV4_PATTERN = Pattern.compile(
"^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
"([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
/**
* Check if valid IPV4 address.
*
* @param input the address string to check for validity.
* @return True if the input parameter is a valid IPv4 address.
*/
public static boolean isIPv4Address(String input) {
return IPV4_PATTERN.matcher(input).matches();
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2021/1/7补充,设置当前连接的wifi为静态IP或自动获取IP ,在安卓5.1.1测试通过,这样就不需要传入SSID,密码和加密方式了。
/**
* @param context use Application context is better
* @param ipAddress ip address: like 192.168.1.168
* @param mode : STATIC or DHCP, set static or dhcp ip mode
* @param netmask ip mask, like 255.255.255.0
* @param gateway gateway, like 192.168.1.1
* @param dns1 dns 1
* @param dns2 dns 2, if mode=static, then can use "" or null
* eg. dhcp mode: setWifiStaticIP(ApplicationContext, "DHCP", "", "", "", "", "");
* static mode: setWifiStaticIP(ApplicationContext, "STATIC",
* "192.168.1.168", "255.255.255.0",
* "192.168.1.1", "114.114.114.114", "8.8.8.8");
* for android 9.0 or 5.1
*/
public boolean setWifiStaticIP(Context context, String mode, String ipAddress, String netmask,
String gateway, String dns1, String dns2) {
if (context == null || (!"STATIC".equals(mode) && !"DHCP".equals(mode))) {
Log.d(TAG, " setWifiStaticIP failed, param incorrect context=" + context + ", mode=" + mode);
return false;
}
try {
WifiManager wifiManager = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE));
if ("DHCP".equals(mode)) {
IpConfiguration dhcpConfiguration = new IpConfiguration(IpConfiguration.IpAssignment.DHCP,
IpConfiguration.ProxySettings.NONE, null, null);
dhcpConfiguration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
WifiConfiguration wifiConfiguration = getCurrentConfig();
if (wifiConfiguration != null) {
wifiConfiguration.setIpConfiguration(dhcpConfiguration);
// current assignment is DHCP OR STATIC
String assignMent = wifiConfiguration.getIpConfiguration().ipAssignment.name();
Log.d(TAG, " setWifiStaticIP assignMent=" + assignMent + ", mode=" + mode);
wifiManager.setWifiApConfiguration(wifiConfiguration);
// update network
wifiManager.updateNetwork(wifiConfiguration);
// reconnect
int netId = wifiManager.addNetwork(wifiConfiguration);
wifiManager.disableNetwork(netId);
wifiManager.enableNetwork(netId, true);
Log.i(TAG, " setWifiStaticIP dhcp set success");
return true;
} else {
return false;
}
}
// set static ip address
IpConfiguration ipConfiguration = getStaticIpConfiguration(ipAddress, netmask, gateway, dns1, dns2);
if (ipConfiguration != null) {
WifiConfiguration wifiConfiguration = getCurrentConfig();
if (wifiConfiguration != null) {
wifiConfiguration.setIpConfiguration(ipConfiguration);
wifiManager.setWifiApConfiguration(wifiConfiguration);
// update network
wifiManager.updateNetwork(wifiConfiguration);
// reconnect
int netId = wifiManager.addNetwork(wifiConfiguration);
wifiManager.disableNetwork(netId);
wifiManager.enableNetwork(netId, true);
Log.i(TAG, "setWifiStaticIP set static ip success");
return true;
} else {
return false;
}
} else {
Log.w(TAG, "setWifiStaticIP set static ip failed");
return false;
}
} catch (Exception e) {
Log.e(TAG, "setWifiStaticIP e=" + e.getMessage());
}
return false;
}
/**
* 获取当前网络配置信息
*/
public WifiConfiguration getCurrentConfig()
{
WifiManager mWifiManager = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE));
WifiInfo connectionInfo = mWifiManager.getConnectionInfo(); //得到连接的wifi网络
WifiConfiguration wifiConfig = null;
List<WifiConfiguration> configuredNetworks = mWifiManager.getConfiguredNetworks();
for (WifiConfiguration conf : configuredNetworks) {
if (conf.networkId == connectionInfo.getNetworkId()) {
wifiConfig = conf;
break;
}
}
return wifiConfig;
}
因为部分api在framework.jar中才有,所以需要导入framework.jar作为依赖,另外测试时app用了platform签名。
framework.jar可以在GitHub - zzhceo/EthernetStaticIp: For Android 9.0 set ethernet static/dhcp ip address获取。
在模块的build.gradle中加入依赖framework.jar方式如下:
dependencies {
//... ...
// framework.jar placed in app/libs directory
compileOnly files('libs/framework.jar')
}
-------------------------------------20240530更新-----------------------------------------------------------------------
注意:需要将framework.jar的api被调用优先级,优先于其他的jar包,需要调整jar包优先级,见我的另一篇文章:
将framework.jar API优先于SDK API被调用和识别,支持将多个jar中的api优先级排序。_android 导入系统 jar包,编译时优先于查找系统sdk-CSDN博客
部分参考:关于Android 5.0 、6.0 、 7.0代码设置WIFI连接方式为静态IP或DHCP的方法及注意事项_ai编程 java 安卓7.0连接到指定的 wifi-CSDN博客
以太网静态、动态IP设置可参考我的另一篇文章:安卓9.0设置以太网静态IP地址_android ethernetmanager.setconfiguration必须重启才能生效-CSDN博客