Setting up the library

This article describes the general flow of using the micro VPN SDK library in your app. The following steps might sometimes refer to micro VPN SDK as MAM SDK:

  1. Open the Android project in an integrated development environment (IDE).

  2. Add a file named mamsdk.properties in the project’s root folder. Update mamSdkVersion and appPackageName properties with the correct values.

     ##### Enter MAM SDK Maven library URL #####
     mamSdkLibraryMaven=https://raw.githubusercontent.com/citrix/citrix-mam-sdks/main/maven
        
     ##### Enter MAM SDK Tools library URL #####
     mamSdkLibraryTools=https://github.com/citrix/citrix-mam-sdks/raw/main/tools/java
        
     ##### Enter the latest MAM SDK version number (e.g. 23.1.0.+) #####
     mamSdkVersion=22.9.0.+
        
     ##### Enter the App's Package Name (e.g. com.citrix.mvpntestapp). Package name has to be globally unique #####
     appPackageName=
    
  3. Add a file named keystore.properties in the project’s root folder. Update all properties with the correct values.

     #### Enter KeyStore Path (e.g. <folder location>/mycompany.keystore )  #####
     keyStorePath=
        
     #### Enter Keystore Password #####
     keystorePassword=
        
     #### Enter Key Alias #####
     keyAlias=
        
     #### Enter Key Password #####
     keyPassword=
    
  4. Open the build.gradle file under the project’s root folder. Add the following script to read these external properties from mamsdk.properties and keystore.properties files. This script should be added before the allprojects tag.

     // Load KeyStore properties
     def keystorePropertiesFile = rootProject.file("keystore.properties")
     def keystoreProperties = new Properties()
     keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
     // Load Citrix MAM SDK properties
     def mamsdkPropertiesFile = rootProject.file("mamsdk.properties")
     def mamsdkProperties = new Properties()
     mamsdkProperties.load(new FileInputStream(mamsdkPropertiesFile))
    
     ext {
         mamSdkLibraryMaven = mamsdkProperties['mamSdkLibraryMaven']
         if (mamSdkLibraryMaven.isEmpty()) {
             throw new GradleException('ERROR: mamSdkLibraryMaven property value is missing in mamsdk.properties.')
         }
         println 'mamSdkLibraryMaven:' + mamSdkLibraryMaven
         mamSdkLibraryTools = mamsdkProperties['mamSdkLibraryTools']
         if (mamSdkLibraryTools.isEmpty()) {
             throw new GradleException('ERROR: mamSdkLibraryTools property value is missing in mamsdk.properties.')
         }
         println 'mamSdkLibraryTools:' + mamSdkLibraryTools
         mamSdkVersion = mamsdkProperties['mamSdkVersion']
         if (mamSdkVersion.isEmpty()) {
             throw new GradleException('ERROR: mamSdkVersion property value is missing in mamsdk.properties.')
         }
         println 'mamSdkVersion:' + mamSdkVersion
         appPackageName = mamsdkProperties['appPackageName']
         if (appPackageName.isEmpty()) {
             throw new GradleException('ERROR: appPackageName property value is missing in mamsdk.properties.')
         }
         println 'appPackageName:' + appPackageName
         keyStorePath = keystoreProperties['keyStorePath']
         if (keyStorePath.isEmpty()) {
             throw new GradleException('ERROR: keyStorePath property value is missing in keystore.properties.')
         }
         println 'keyStorePath:' + keyStorePath
         keystorePassword = keystoreProperties['keystorePassword']
         if (keystorePassword.isEmpty()) {
             throw new GradleException('ERROR: keystorePassword property value is missing in keystore.properties.')
         }
         keyAlias = keystoreProperties['keyAlias']
         if (keyAlias.isEmpty()) {
             throw new GradleException('ERROR: keyAlias property value is missing in keystore.properties.')
         }
         keyPassword = keystoreProperties['keyPassword']
         if (keyPassword.isEmpty()) {
             throw new GradleException('ERROR: keyPassword property value is missing in keystore.properties.')
         }
     }
    
  5. Add the maven repository URL to point to the micro VPN maven library. This needs to be added within the allprojects tag in the build.gradle file under the project’s root folder.

     repositories {
         maven { url "$rootProject.ext.mamSdkLibraryMaven" }
         google()
         mavenCentral()
         jcenter()
     }
    
  6. Open the build.gradle file inside the project’s app module. Add the following Gradle dependency to use the micro VPN library:

     dependencies {
         implementation "com.citrix.android.sdk:mamsdk:${rootProject.ext.mamSdkVersion}"
     }
    
  7. Within the same file, enable support for desugar bytecode transformations by adding the compileOptions tag within the android tag.

     android {
         compileOptions {
             sourceCompatibility JavaVersion.VERSION_1_8
             targetCompatibility JavaVersion.VERSION_1_8
         }
     }
    
  8. Within the same file, in the android > defaultConfig tag, modify the applicationId to have the appPackageName from mamsdk.properties.

     applicationId "${rootProject.ext.appPackageName}"
    
  9. Within the same file, add signingConfigs for the debug and release builds. Provide the KeyStore path, store password, key alias, and key password.

     android {
         signingConfigs {
             debug {
                 storeFile file(rootProject.ext.keyStorePath)
                 storePassword "$rootProject.ext.keystorePassword"
                 keyAlias "$rootProject.ext.keyAlias"
                 keyPassword "$rootProject.ext.keyPassword"
             }
             release {
                 storeFile file(rootProject.ext.keyStorePath)
                 storePassword "$rootProject.ext.keystorePassword"
                 keyAlias "$rootProject.ext.keyAlias"
                 keyPassword "$rootProject.ext.keyPassword"
             }
         }
         buildTypes {
             release {
                 minifyEnabled false
                 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
                 signingConfig signingConfigs.release
             }
             debug {
                 signingConfig signingConfigs.debug
             }
         }
     }
    
  10. If your app has ProGuard settings enabled, then add the following to your ProGuard file(Eg. proguard-rules.pro):

     -keep class com.citrix.** {*;}
     -keepattributes Exceptions
    
  11. Add the following Gradle plugin in the build.gradle file under the app module. This can be added after the buildscript or plugin tag.

     plugins {
         id "de.undercouch.download" version "4.1.1"
     }
    
  12. Add the Gradle tasks generateMdx, and downloadTools in the build.gradle file under the app module and finalize the build with the generateMdx task. These tasks are used to download the managed-app-utility.jar file and to generate the MDX file from the APK.

     task downloadTools(type: Download, dependsOn: build) {
         src "${rootProject.ext.mamSdkLibraryTools}/managed-app-utility.jar"
         dest "$buildDir/tools/managed-app-utility.jar"
         overwrite false
     }
     task generateMdx(type: Exec, dependsOn: [downloadTools]) {
         commandLine 'java', '-jar', "$buildDir/tools/managed-app-utility.jar", 'wrap',
                 '-in', "$buildDir/outputs/apk/release/${project.name}-release.apk",
                 '-out', "$buildDir/outputs/apk/release/${project.name}.mdx",
                 '-appType', 'sdkapp',
                 '-storeUrl', "https://play.google.com/store/apps/details?id=${rootProject.ext.appPackageName}",
                 '-keystore', "${rootProject.ext.keyStorePath}",
                 '-storepass', "${rootProject.ext.keystorePassword}",
                 '-keyalias', "${rootProject.ext.keyAlias}",
                 '-keypass', "${rootProject.ext.keyPassword}"
     }
     build.finalizedBy generateMdx
    
  13. Add the following XML clause to the AndroidManifest.xml file within the application tag:

     <uses-library android:name="org.apache.http.legacy" android:required="false" />
    
  14. If the app targets Android SDK API level 30 or above, add the following XML clause within the manifest tag to the Androidmanifest.xml file:

      <queries>
          <package android:name="com.zenprise" />
          <package android:name="com.citrix.Receiver" />
      </queries>
    
  15. Add the line xmlns:tools="http://schemas.android.com/tools" within the <manifest> tag to the AndroidManifest.xml file.

     <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.example.package"
         xmlns:tools="http://schemas.android.com/tools">
    
  16. Add the line tools:replace="android:theme" within the <application> tag to the AndroidManifest.xml file.

     <application
         …
         …
         tools:replace="android:theme">
    
  17. Run the Gradle build using the following command:

     ./gradlew clean build
    

    After the build completes, the generateMdx task creates an MDX file in the app/build/outputs/apk/release folder.

  18. To distribute your app, see Distribute apps.

  19. For any issues, see the Troubleshooting guide.

Setting up the library

In this article