2016-10-20 17 views
12

Statik IP ve ağ geçidini Android 6'da programsal olarak nasıl ayarlayabilirim?Statik IP'yi ve ağ geçidini Android'de programsal olarak ayarlayın 6.x (Marshmallow)

here ve here okudum.

Settings.System artık çalışmıyor ve goolgle, API düzeyi 17'de WIFI_STATIC_IP kullanımdan kaldırılmış ve bunun yerine WifiManger kullanın. Maalesef bu konuda WifiManger ve WifiConfiguration sınıflarında hiçbir şey bulamıyorum.

+0

Peki neden https://stackoverflow.com/questions/10278461/how-to-configue-a-static-ip-address-netmask-gateway-programmatically gelen bu farklı -on-androi? – Fabio

+0

@Fabio, aygıt sahibini ayarlamadıkça başvurulan örneklerdeki öneriler çalışmaz. – Knubo

cevap

7

Resmi bir API olmadığı için, aşağıdaki code snipet ve this answer'dan örnekleri değiştirerek bir çözüm bulmak zorundayım. Bu çözüm, Lollipop cihazlarından yukarı doğru çalışır.

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

Yardımcısı fonksiyonları,

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

Kullanmak için,

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

Son olarak

<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

Android API ile çalışmadığımdan, birileri kontrol edip bana bir onay yazmasını söyleyebilir mi? – Mogi

+0

@Mogi bu ne anlama geliyor? API ile çalışmıyorsunuz? ne ile çalışıyorsun? Sadece bu kodu alıp uygulamaya ekleyin ve uygulamayı kullanmaya çalışın. çalışıp çalışmadığını bileceksiniz! – Yazan

+0

@Yazan Yanlış anladım :) Artık android ile çalışmıyorum ve soru Ekim 2016'da sorulmuş! Bu arada İŞİMİ değiştirdim.haha – Mogi

2

Bazıları soruna kazdık ve bulgularım, aygıtın aygıt sahibi olması için Andrdoi 5.x için kullanılan kodun çalışabilmesi olabilir.

Çözüm:

çözeltisi DeviceOwner olarak cihaz eklemektir. Bu, statik IP'nin Mogi tarafından başvurulan 5.x hack'lar kullanılarak ayarlanmasına izin verecektir. Bu örneği kullandığını nasıl yapıldığını iyi bir örnek burada bulunabilir:

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

onun işi yapmak için izin verilmesi için hazır hale getirecek:

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

komutunu adb kabuk kullanma ve çalıştırma .

0

başarıyla eklemiş manifest'te bu izinleri eklemeniz gerekir ve açık ve PSK ne bağlı Benim app programatik olarak tworks (5.1 ve 6.0 çalıştıran cihazlar üzerinde çalıştı). Ancak bunu kurumsal ağ için denediğimde işe yaramıyor. AddNetwork() 'in başarılı olduğunu görüyorum (pozitif net kimliğini döndürür) ancak Ayarlar-> Wi-Fi altında baktığımda eklediğim diğer SSID'ler için yaptığım gibi SSID'yi göremiyorum. Bunun neden olacağını bilen var mı? WiFiConfiguration listesini programlı olarak ararsam, SSID'yi bulur. İşte kod kullanmak edilir:

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(); 
İlgili konular