Es gibt leider immer noch keine offene API.
Die Lösung für Android 4.0 funktioniert in LOLLIPOP nicht, da Dinge verschoben wurden. Insbesondere die neue Klasse IpConfiguration
enthält jetzt die StaticIpConfiguration
und all diese Felder. Sie können immer noch zugänglich gemacht werden, indem Reflektion (mit all der damit verbundenen Sprödigkeit) mit so etwas verwendet wird.
Warnung, dieser Code ist nur Android 5.0. Sie müssen Build.VERSION.SDK_INT
überprüfen und entsprechend handeln.
@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();
}
Mit den folgenden Hilfsmethoden Reflexion zu handhaben:
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);
}
Zum Beispiel können Sie es so nennen:
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();
}
}
}
Als Referenz, könnten Sie nehmen wollen ein Blick auf die WifiConfigController
Klasse im Framework (obwohl es diese Klassen direkt anstelle von Reflektion verwendet).
Mann das ist erstaunlich, getestet Ihren Code und es funktioniert! Du bist der Beste :) – KennyPowers
Dies wäre auch ein gutes Beispiel für mich, wie versteckte Android-Klassen zu reflektieren. – KennyPowers
Ich weiß, es ist eine andere Frage, aber 100% bezogen auf das Thema: Wie bekomme ich die derzeit funktionierenden DNS-ID-Adressen? – KennyPowers