gpt4 book ai didi

java - 如何在 Android 5.x (Lollipop) 上以编程方式为 Wi-Fi 连接配置静态 IP 地址、网络掩码、网关、DNS

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:22:45 26 4
gpt4 key购买 nike

如何在 Android 5.x 上以编程方式配置静态 IP 地址、网络掩码、网关、DNS 以进行 Wi-Fi 连接?是否有一个开放的 API(没找到)或隐藏的可以用于此?如果可能的话,您能否再举一些例子。

我知道它是 possible on 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框架中的类(尽管它直接使用这些类而不是通过反射)。

关于java - 如何在 Android 5.x (Lollipop) 上以编程方式为 Wi-Fi 连接配置静态 IP 地址、网络掩码、网关、DNS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27599564/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com