I know that android.net.VpnService is basically the base class for creating custom vpn solutions, but all I want to do is create and use a PPTP or L2TP VPN connection (just a new profile for the built-in VPN manager). I think the easiest way to do this is to use Java reflection for com.android.settings.vpn.VpnSettings. Here's a code snippet for this from another post ( How do I add my own VPN settings to the VPN system settings page? )
package com.nikola.despotoski.whatever; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class VpnSetter { private static Map<String , Class<?>> getMappedFields(){ Map<String , Class<?>> fieldsAndTypes = new HashMap<String, Class<?>>(); fieldsAndTypes.put("name", String.class); // 0 fieldsAndTypes.put("type" , int.class); // 1 fieldsAndTypes.put("server", String.class); // 2 fieldsAndTypes.put("username", String.class); fieldsAndTypes.put("password", String.class); fieldsAndTypes.put("dnsServers", String.class); fieldsAndTypes.put("searchDomains", String.class); fieldsAndTypes.put("routes", String.class); fieldsAndTypes.put("mppe", boolean.class); fieldsAndTypes.put("l2tpSecret", String.class); fieldsAndTypes.put("ipsecIdentifier", String.class); fieldsAndTypes.put("ipsecSecret", String.class); fieldsAndTypes.put("ipsecUserCert", String.class); fieldsAndTypes.put("ipsecCaCert", String.class); fieldsAndTypes.put("saveLogin", boolean.class); return fieldsAndTypes; } public static final Set<String> VPN_PROFILE_KEYS = getMappedFields().keySet(); // contains keys for quicker generation of key-value map for each public static void addVpnProfile(String vpnProfileKey, Map<String, Object> values) throws ClassNotFoundException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException{ Class<?> vpnSettings = Class.forName("com.android.settings.vpn2.VpnSettings"); Class<?>[] privateVpnSettingsClasses = vpnSettings.getDeclaredClasses(); Class<?> vpnPreference = null; Class<?> vpnProfileClass = Class.forName("com.android.settings.vpn2.VpnProfile"); for(Class<?> priv :privateVpnSettingsClasses ){ if(priv.getName().equals("VpnPreference")){ vpnPreference = priv; break; } } Field vpnProfileFromVpnPreferenceField = vpnPreference.getDeclaredField("mProfile"); vpnProfileFromVpnPreferenceField.setAccessible(true); Object vpnProfile = vpnProfileFromVpnPreferenceField.get(vpnProfileClass); Constructor<?> constructor = vpnProfileFromVpnPreferenceField.getClass().getConstructors()[0]; constructor.setAccessible(true); vpnProfile = constructor.newInstance(vpnProfileKey);//creating new instance of VpnProfile class Map<String, Class<?>> vpnProfileMap = getMappedFields(); Iterator<String> profileKeysIterator = vpnProfileMap.keySet().iterator(); while(profileKeysIterator.hasNext()){ String key = profileKeysIterator.next(); Field field = vpnProfile.getClass().getField(key); field.setAccessible(true); if(vpnProfileMap.get(key).equals(String.class) && values.get(key)!=null){ String s = new String(); field.set(s, "value");//change this }else if(vpnProfileMap.get(key).equals(boolean.class) && values.get(key)!=null){ int i = 0; field.setInt(i, 1111111);// change this }else if(values.get(key)!=null){ boolean b = false; field.setBoolean(b, true);// change this } } vpnSettings = Class.forName("com.android.settings.vpn.VpnSettings"); //time to add it to settings Method addProfileMethod = vpnSettings.getDeclaredMethod("addProfile", vpnProfile.getClass()); addProfileMethod.setAccessible(true); addProfileMethod.invoke(vpnSettings, vpnProfile); } }
When I run this code, I get: java.lang.classnotfoundexception: com.android.settings.vpn2.vpnsettings
Just that to know what I'm doing wrong. I tried with API 14, 15 .. 18 Devices are not deployed.
If you have another suggestion on how to add a new profile to the built-in VPN manager, please let me know.