Как настроить статический IP-адрес, сетевую маску, шлюз, DNS программно на Android 5.x (Lollipop) для подключения Wi-Fi

Как можно настроить статический IP-адрес, сетевую маску, шлюз, DNS на Android 5.x для подключения Wi-Fi? Есть ли открытый API (не нашел его), или скрытые могут быть использованы для этого? Не могли бы вы также привести несколько примеров, если это возможно.

Я знаю, что это возможно на Android 4.0+, но он не работает на Android 5.0

К сожалению, до сих пор нет открытого API.

Решение для Android 4.0 не работает в LOLLIPOP, потому что все перемещено. В частности, новый класс IpConfiguration теперь содержит StaticIpConfiguration и все эти поля. Их все еще можно получить, используя отражение (со всей хрупкостью, которая влечет за собой) с чем-то вроде этого.

Предупреждение, этот код – только для Android 5.0. Вам нужно будет проверить Build.VERSION.SDK_INT и действовать соответствующим образом.

 @SuppressWarnings("unchecked") private 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); getField(staticIpConfig, "dnsServers", ArrayList.class).clear(); for (int i = 0; i < dns.length; i++) getField(staticIpConfig, "dnsServers", ArrayList.class).add(dns[i]); callMethod(config, "setStaticIpConfiguration", new String[] { "android.net.StaticIpConfiguration" }, new Object[] { staticIpConfig }); manager.updateNetwork(config); manager.saveConfiguration(); } 

Со следующими вспомогательными методами обработки отражения:

 private static Object newInstance(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { return newInstance(className, new Class<?>[0], new Object[0]); } 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<Enum> enumClz = (Class<Enum>)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 <T> T getField(Object object, String fieldName, Class<T> type) throws IllegalAccessException, IllegalArgumentException, NoSuchFieldException { Field field = object.getClass().getDeclaredField(fieldName); return type.cast(field.get(object)); } 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 void test(Context context) { WifiManager manager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); WifiConfiguration wifiConf = ... /* Get Wifi configuration you want to update */ if (wifiConf != null) { try { setStaticIpConfiguration(manager, wifiConf, InetAddress.getByName("10.0.0.1"), 24, InetAddress.getByName("10.0.0.2"), new InetAddress[] { InetAddress.getByName("10.0.0.3"), InetAddress.getByName("10.0.0.4") }); } catch (Exception e) { e.printStackTrace(); } } } 

В качестве ссылки вы можете взглянуть на класс WifiConfigController в рамках (хотя он использует эти классы напрямую, а не через отражение).

IP-адреса настраиваются на интерфейсе, а не на телефоне. Вы не можете установить один IP-адрес, который будет использоваться для сотового подключения к данным, а также все беспроводные (bluetooth и т. Д.) Соединения, которые могут быть созданы.

Поскольку IP-адрес зависит от интерфейса, адрес также настроен там.

Для подключения к данным IP-адрес (я считаю, не подтвержден) передается на мобильный телефон сотовым оператором и не настраивается на устройстве.

Для регулярных соединений типа wi-fi для каждой сети вы можете использовать настройку по умолчанию (DHCP) или какую-либо другую форму предоставления IP-адресов, в том числе, хотите ли вы настроить IP-адрес вручную или через динамические системы на месте.

Поскольку в сети также установлены шлюз и сетевая маска, имеет смысл, что «лучший» способ настроить «статический» IP-адрес для данной сети – это настроить его на стороне сети. Для большинства сетевых серверов DHCP вы можете настроить их, чтобы каждый раз предоставлять один и тот же сетевой IP-адрес одному и тому же устройству.

Это то, что я делаю, у меня есть определенные устройства, которые получают свой IP-адрес через DHCP, но DHCP-сервер всегда выделяет один и тот же предварительно сконфигурированный и «статический» IP-адрес для устройств, которые я хочу постоянно (и другие устройства вытаскивают IP из доступных 'бассейн').