2016-10-20 2 views
12

Может ли кто-нибудь сказать мне, как я могу установить статический IP-адрес и шлюз программно в Android 6?Установить статический IP-адрес и шлюз программно в Android 6.x (Marshmallow)

Я прочитал here и here.

Settings.System больше не работает, а goolgle говорит, что WIFI_STATIC_IP устарел на уровне API 17 и вместо этого использует WifiManger. К сожалению, я ничего не могу с этим поделать в классах WifiManger и WifiConfiguration.

+0

Так почему же это отличается от https://stackoverflow.com/questions/10278461/how-to-configue-a-static-ip-address-netmask-gateway-programmatically -он-андрои? – Fabio

+0

@Fabio предложения в приведенных примерах не работают, если вы не установили владельца устройства. – Knubo

ответ

7

Поскольку нет официального API, я должен придумать решение, изменив образцы из следующих code snipet и this answer. Это решение работает на устройствах от Lollipop вверх.

@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); 
     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}); 

     int netId = manager.updateNetwork(config); 
     boolean result = netId != -1; 
     if (result) { 
      boolean isDisconnected = manager.disconnect(); 
      boolean configSaved = manager.saveConfiguration(); 
      boolean isEnabled = manager.enableNetwork(config.networkId, true); 
      boolean isReconnected = manager.reconnect(); 
     } 
    } 

Вспомогательные функции,

public static WifiConfiguration getCurrentWiFiConfiguration(Context context) { 
      WifiConfiguration wifiConf = null; 
      ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
      NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 
      if (networkInfo.isConnected()) { 
       final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 
       final WifiInfo connectionInfo = wifiManager.getConnectionInfo(); 
       if (connectionInfo != null && !TextUtils.isEmpty(connectionInfo.getSSID())) { 
        List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks(); 
        if (configuredNetworks != null) { 
         for (WifiConfiguration conf : configuredNetworks) { 
          if (conf.networkId == connectionInfo.getNetworkId()) { 
           wifiConf = conf; 
           break; 
          } 
         } 
        } 
       } 
      } 
      return wifiConf; 
     } 

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); 
    } 

использовать его,

WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 
WifiConfiguration wifiConf = WifiHelper.getCurrentWiFiConfiguration(getApplicationContext()); 

     try { 
      setStaticIpConfiguration(wifiManager, wifiConf, 
        InetAddress.getByName("192.168.0.100"), 
        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(); 
     } 

Наконец, вам нужно добавить эти разрешения в манифесте,

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.WRITE_SETTINGS" /> 
+0

Поскольку я не работаю с API андроида, может кто-нибудь проверить его и сказать мне, чтобы поставить галочку на нем? – Mogi

+0

@ Моги, что это значит? вы не работаете с API? с чем вы работаете? просто возьмите этот код, добавьте его в ur-приложение, а затем попробуйте использовать это приложение. вы узнаете, работает оно или нет! – Yazan

+0

@Yazan u понимаете это неправильно :) Я больше не работаю с андроидом, и вопрос был задан в октябре 2016 года! Я изменил свою РАБОТУ тем временем.haha – Mogi

2

Я искал некоторые проблемы, и мои выводы заключаются в том, что код, который использовался для работы с Andrdoi 5.x, может работать, если приложение установлено как владелец устройства.

Решение:

Решение состоит в том, чтобы добавить устройство в качестве deviceOwner. Это позволит установить статический IP-адрес, используя хаки 5.x, как указано Mogi. Хороший пример того, как это делается, используя пример здесь:

https://github.com/googlesamples/android-DeviceOwner/

Использование ADB оболочки и выполнив команду:

dpm set-device-owner com.example.android.deviceowner/.DeviceOwnerReceiver 

сделает его готовым, чтобы иметь возможность выполнять свою работу ,

0

Я успешно добавлен и подключен к open и PSK ne tworks программно в моем приложении (проверено на устройствах с 5.1, а также 6.0). Однако, когда я пытаюсь это сделать для корпоративной сети, он не работает. Я вижу, что addNetwork() успешно (возвращает положительный идентификатор сети), но когда я смотрю в разделе «Настройки»> «Wi-Fi», я не вижу SSID, как я делаю для других SSID, которые я добавил. Кто-нибудь знает, почему это было бы? Если я программно просматриваю список WiFiConfiguration, он найдет SSID. Вот код я использую:

wifiConf = new WifiConfiguration(); 
wifiConf.SSID = "\"dot1x-test\""; 
wifiConf.BSSID = "c4:e9:84:43:48:e8"; 
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { 
    wifiConf.enterpriseConfig.setIdentity("name"); 
    wifiConf.enterpriseConfig.setPassword("testpassword"); 
    wifiConf.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP); 
    wifiConf.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2); 
} 

netId = wifiMgr.addNetwork(wifiConf); 
wifiMgr.disconnect(); 
wifiMgr.enableNetwork(netId, true); 
wifiMgr.saveConfiguration(); 
wifiMgr.reconnect(); 
Смежные вопросы