我知道android.net.VpnService基本上是构建自定义vpn解决方案的基类,但我想要的只是创建和使用PPTP或L2TP VPN连接(只是内置VPN管理器的新配置文件)。 我认为最简单的方法是使用Java反射来进行com.android.settings.vpn.VpnSettings。以下是其他帖子(How to add own VPN settings to system VPN 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);
}
}
当我运行此代码时,我得到:java.lang.classnotfoundexception: com.android.settings.vpn2.vpnsettings
知道我做错了什么。我尝试使用API 14,15 .. 18 设备未植根。
如果您有其他建议如何将新配置文件添加到内置VPN管理器,请告诉我们。
答案 0 :(得分:4)
基本上,您尝试的内容无法正常运行,因为您的应用中无法使用VpnSettings
课程。它不是Android框架的私有部分;它是Settings应用程序的一部分,它是一个与您完全独立的应用程序。这就像尝试从Firefox应用程序访问org.mozilla.firefox.App
类一样。你不能这样做。如果可以的话,您会发现它仍然不起作用,因为VpnSettings
会将其设置保存到您的应用无权访问的位置。
如果您的设备 已根,并且您的应用具有超级用户权限,则您可以自行写入该位置。否则,你就没有机会了。
答案 1 :(得分:1)
所以似乎将我的Android Project Build Target更改为Google API目标而不仅仅是Android目标已经修复了问题(或者至少我不再再获得ClassNotFoundException了。)
尝试自己设置:右键单击您的项目。构建路径 - &gt;配置构建路径...转到左窗格中的Android设置。检查项目的相应Google API目标。
编辑:这解决了我遇到的VpnProfile
问题,但没有解决您所拥有的VpnSettings
问题(现在我遇到了这个问题)。
编辑2:VpnSettings类位于“设置”应用中。如果您愿意,可以下载“设置”应用的来源:https://android.googlesource.com/platform/packages/apps/Settings.git