VPN Unlimited SDK for Android is shipped as a distribution of an Android Library Project. It is written in Java and C++ and is available for Android 4.0 and later.
Drag and drop VpnUnlimitedSDK.aar into your project libs folder.
In order to use it you have to add following lines of code to yours build.gradle
dependencies { implementation 'com.keepsolid.androidkeepsolidcommon:VpnUnlimitedSDK@aar' }
for the correct work of SDK, you must also add the following dependencies:
implementation 'com.madgag.spongycastle:bcpkix-jdk15on:1.58.0.0' implementation 'com.madgag.spongycastle:bcpg-jdk15on:1.58.0.0' api 'com.google.code.gson:gson:2.10.1' api 'com.squareup.okhttp3:okhttp:3.14.9' api 'org.conscrypt:conscrypt-android:2.2.1'
After setup is done you should be able to use all the classes from SDK by including it with import com.keepsolid.androidkeepsolidcommon.*; directive.
Current version of VPN Unlimited SDK uses the following libraries under the hood:
If your project uses one of these libraries and you get conflicts please contact VPN Unlimited team for further investigation.
Use the following setup code in your Application class onCreate() method to initialize VPN Unlimite SDK using your App ID and App Secret:
VPNUFacade.getInstance().prepare(getApplicationContext(), Constants.APPLICATION_ID, Constants.APPLICATION_SECRET);
To ensure the correct display of the dialogs from the VPN Unlimited SDK and the normal operation of the listeners to the VPN connection status, please follow the next steps:
In your project, create a class that extends KSDefaultDialogActivity and specify it in the Manifest file as Activity with Intent-Filter set to Action: your.application.package.name.DialogActivity.LAUNCH_INTENT_ACTION.
public class BaseDialogActivity extends KSDefaultDialogActivity { @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); } }
<activity android:name=".BaseDialogActivity" android:excludeFromRecents="true"> <intent-filter> <action android:name="your.application.package.name.DialogActivity.LAUNCH_INTENT_ACTION" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
Note that you need to replace your.application.package.name with the real package name of your application.
Add the special receiver configured as shown below to the Manifest file. In this case, you also need to replace your.application.package.name with the real package name of your application.
<receiver android:name="com.keepsolid.androidkeepsolidcommon.vpnunlimitedsdk.vpn.controllers.VPNUStateController" android:label="VPNUStateController"> <intent-filter> <action android:name="your.application.package.name.OpenVpnService.OPEN_VPN_STATE_BROADCAST_ACTION" /> <action android:name="your.application.package.name.OpenVpnService.ENABLE_VPN_CONNECTION_BROADCAST_ACTION" /> <action android:name="your.application.package.name.OpenVpnService.DISABLE_VPN_CONNECTION_BROADCAST_ACTION" /> <action android:name="your.application.package.name.OpenVpnService.CHECK_SERVICE_CONNECTION_BROADCAST_ACTION" /> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
To support Android 13+ (api33+) you need to add new permissions to manifest file
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>>
also you need to request notification permission in proper way.
This SDK is designed in classical OOP style. We don't provide one single interface, but rather a handful of interfaces which you can use in any desired combination. All network calls are synchronous, so you should never call them from main thread. This limitation is highlighted by the fact, that you actually can perform several steps in a row serially on secondary thread and come back to main thread with a desired result.
Here is the complete list of classes:
You can see the complete documentation for each class at Reference page.
Here we just briefly describe the standard workflow.
The VPNUFacade is to some degree the main class in SDK. It provides interfaces to all SDK APIs, namely:
As stated previously, all network calls in this SDK are performed synchronously. That means that you should perform them all on a non-main thread, otherwise it would block it and never come back. Every method which falls into this category is explicitly documented.
In every example in the FAQ section it is implicitly considered that SDK is set up properly before any calls:
VPNUFacade.getInstance().prepare(getApplicationContext(), Constants.APPLICATION_ID, Constants.APPLICATION_SECRET);
It is also considered that the code is executing on a secondary thread, for example:
new Thread(new Runnable() { @Override public void run() { //SDK calls } }).start();
First, setup VPNUAuthorizer instance.
VPNUAuthorizer vpnuAuthorizer = VPNUFacade.getInstance().getVpnuAuthorizer();
Then, you can log in using user's credentials:
String login = "login@some.domain"; String password = "password"; try { VPNUAccountUserInfo userInfo = vpnuAuthorizer.authorizeWithLogin(login, password); } catch (VPNUException exception) { Log.v(LOG_TAG, "authorization failed with error code: " + exception.getResponse().getResponseCode() + ", and error msg " + exception.getResponse().getResponseMessage()); exception.printStackTrace(); }
If authorization is successful, the VPNUTransport instance is managing the newly created session and reconnects automatically when this session is expired. Retrieved authorization info is saved into VPNUAccountUserInfo
First, setup VPNUAuthorizer instance.
VPNUAuthorizer vpnuAuthorizer = VPNUFacade.getInstance().getVpnuAuthorizer();
Then, you can register new user using user's credentials. VPNUAuthorizer#registerWithLogin will automatically log in a newly created user.
String login = "login@some.domain"; String password = "password"; try { userInfo = VPNUFacade.getInstance().authorizer.registerWithLogin(email, password, false) } catch (VPNUException exception) { Log.v(LOG_TAG, "registration failed with error code: " + exception.getResponse().getResponseCode() + ", and error msg " + exception.getResponse().getResponseMessage()); exception.printStackTrace(); }
You have to be logged in in order to perform this operation successfully. See two previous answers.
boolean signOutSuccessful = false; try { signOutSuccessful = vpnuAuthorizer.logOut(); //or /* /. VPNUFacade.getInstance().vpnuConfigurator.onLogout() */ } catch (VPNUException exception) { Log.v(LOG_TAG, "Log out failed with error code: " + exception.getResponse().getResponseCode() + ", and error msg " + exception.getResponse().getResponseMessage()); exception.printStackTrace(); }
also, you need to stop vpn connection and delete all user data
Assuming you are logged in:
try { VPNUAccountManager vpnuAccountManager = VPNUFacade.getInstance().getVpnuAccountManager(); VPNUAccountStatus accountStatus = vpnuAccountManager.getStatus(); } catch (VPNUException exception) { Log.v(LOG_TAG, "Status loading failed with error code: " + exception.getResponse().getResponseCode() + ", and error msg " + exception.getResponse().getResponseMessage()); exception.printStackTrace(); }
try { VPNUServersManager vpnuServersManager = VPNUFacade.getInstance().getVpnuServersManager(); List<VPNUServer> servers = vpnuServersManager.getServers(); } catch (VPNUException exception) { Log.v(LOG_TAG, "Servers list loading failed with error code: " + exception.getResponse().getResponseCode() + ", and error msg " + exception.getResponse().getResponseMessage()); exception.printStackTrace(); }
First, setup VPNUConfigurator instance.
VPNUConfigurator vpnuConfigurator = VPNUFacade.getInstance().getVpnuConfigurator();
Then you can setup the selected server item (see previous question on how to retrieve it). You can choose protocol settings for VPN connection by passing VPNUProtoConfig entity as a parameter to the VPNUConfigurator#setup method.
try { VPNUConfigurator vpnuConfigurator = VPNUFacade.getInstance().getVpnuConfigurator(); vpnuConfigurator.prepare(); vpnuConfigurator.setup(server, new VPNUProtoConfig(false, Transport.TCP)); } catch (VPNUException exception) { Log.v(LOG_TAG, "set up of Vpn failed with error code: " + exception.getResponse().getResponseCode() + ", and error msg " + exception.getResponse().getResponseMessage()); exception.printStackTrace(); }
You then can try to connect to a selected server. In order to obtain the connection status, use the OpenVpnStatusChangedListener by passing an instance to the VPNUConfigurator#addOnStatusChangedListener method of VPNUConfigurator. This method blocks a calling thread.
try { VPNUConfigurator vpnuConfigurator = VPNUFacade.getInstance().getVpnuConfigurator(); vpnuConfigurator.startVpn(); } catch (VPNUException exception) { Log.v(LOG_TAG, "start Vpn failed with error code: " + exception.getResponse().getResponseCode() + ", and error msg " + exception.getResponse().getResponseMessage()); exception.printStackTrace(); }
This exception thrown when User not granted VPN permission for app. If permission dialog is never shown to user, You probably need to check BaseDialogActivity implimentation and declaration in manifest file of Your app.
In order to properly display VPN Unlimited SDK dialogs you need to create a class that extends KSDefaultDialogActivityand declare it in the Manifest as an activity with the Intent filter for action: keepsolid.com.androidvpnunlimitedsdk.dialogs.DialogActivity.LAUNCH_INTENT_ACTION.
public class BaseDialogActivity extends KSDefaultDialogActivity { @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); } }
<activity android:name=".BaseDialogActivity" android:excludeFromRecents="true"> <intent-filter> <action android:name="your.application.package.name.DialogActivity.LAUNCH_INTENT_ACTION" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
Note that you need to replace your.application.package.name with the real package name of your application.
Actually, you cannot disable it. The notification is necessary to prevent the Service got killed by the Android OS task manager.
try { VPNUConfigurator vpnuConfigurator = VPNUFacade.getInstance().getVpnuConfigurator(); vpnuConfigurator.stopVpn(); } catch (VPNUException exception) { Log.v(LOG_TAG, "Stop Vpn failed with error code: " + exception.getResponse().getResponseCode() + ", and error msg " + exception.getResponse().getResponseMessage()); exception.printStackTrace(); }