Menu
Menu
inquire
DexProtector Android documentation

Documentation

iOS documentation
Android menu

Android

Implementations and Integrations

Integration via the DexProtector Gradle Plugin

The DexProtector Gradle Plugin (dexprotector-gradle-plugin.jar) is included in every distribution package, and can be used to protect APKs, AABs, and AARs.

The steps are straightforward for integrating DexProtector into your builds:

1. Instruct Gradle Where to Find the DexProtector Gradle Plugin (Root settings.gradle or settings.gradle.kts)

First, it is necessary to tell Gradle where the DexProtector plugin and main executable are located. This is done in the settings.gradle (or settings.gradle.kts) file at the root of the project.

Important: Replace /absolute/path/to/DexProtector/15.0.1 with the actual path to the directory containing the target DexProtector JAR and Gradle plugin (most likely the unpacked distro). It's best to use a path relative to your project if possible (e.g., "${rootDir}/tools/dexprotector/15.0.1").

Kotlin DSL (settings.gradle.kts)
// settings.gradle.kts

pluginManagement {
    repositories {
        google()
        mavenCentral()
        flatDir {
            // Set this path to the directory where DexProtector `.jar` and Gradle plugin are located        
            dirs("path/to/dexprotector-ent-15.0.1") //  [Change path when updating DexProtector version]
        }
    }
}

rootProject.name = "YourAndroidProject"
Groovy DSL (settings.gradle)
// settings.gradle

pluginManagement {
    repositories {
        google()
        mavenCentral()
        flatDir {
            // Set this path to the directory where DexProtector `.jar` and Gradle plugin are located
            dirs 'path/to/dexprotector-ent-15.0.1' // [Change path when updating DexProtector version]
        }
    }
}

rootProject.name = 'YourAndroidProject'

2. Make the DexProtector Gradle Plugin Available to the Build Process (Root build.gradle or build.gradle.kts)

o make the DexProtector plugin and its core executable available to your build process, you need to declare them as buildscript dependencies in your root build.gradle (or build.gradle.kts) file. This involves two steps:

  • Declare the repository: Add a flatDir repository within the buildscript.repositories block, pointing to the same directory as specified in your settings.gradle/settings.gradle.kts. This ensures Gradle can locate the plugin artifacts.
  • Add dependencies: Include the dexprotector-gradle-plugin and dexprotector artifacts to the buildscript.dependencies block.

Important: The path specified in flatDir within buildscript.repositories must precisely match the path you configured in your settings.gradle / settings.gradle.kts.

Kotlin DSL (build.gradle.kts)
// build.gradle.kts

buildscript {
    repositories {
        google()
        mavenCentral()
        flatDir {
            dirs("path/to/dexprotector-ent-15.0.1") // <--- Must match settings.gradle.kts
        }
    }
    dependencies {
        // Add the DexProtector plugin and main executable to Gradle's build classpath.
        classpath(":dexprotector-gradle-plugin:")
        classpath(":dexprotector:")
        // ... other dependencies
    }
}
Groovy DSL (build.gradle)
// build.gradle

buildscript {
    repositories {
        google()
        mavenCentral()
        flatDir {
            dirs 'path/to/dexprotector-ent-15.0.1' // <--- Must match settings.gradle
        }
    }

    dependencies {
        // Add the DexProtector plugin and main executable to Gradle's build classpath.
        classpath ":dexprotector-gradle-plugin:"
        classpath ":dexprotector:"
        // ... other dependencies
    }
}

3. Apply the DexProtector Plugin in the Module (App/Library) build.gradle.kts or build.gradle

Finally, apply the DexProtector plugin to your Android app or library module and specify which DexProtector configuration XML file to use, based on buildTypes and/or productFlavors.

Important: Make sure the line to apply the DexProtector plugin is included after the line applying the plugin specifying the module type, i.e. com.android.application or com.android.library

Kotlin DSL (app/build.gradle.kts or library/build.gradle.kts)
// app/build.gradle.kts (for Android applications)
// or library/build.gradle.kts (for Android libraries)

plugins {
    id("com.android.application") // or id("com.android.library") for libraries
    id("dexprotector") // Apply the DexProtector plugin
    // ... other plugins
}

android {
    namespace = "com.example.yourapp" 
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.yourapp"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }

    signingConfigs {
        create("release") {
            storeFile = file("config/release.keystore")
            storePassword = System.getenv("RELEASE_STORE_PASSWORD")
            keyAlias = System.getenv("RELEASE_KEY_ALIAS")
            keyPassword = System.getenv("RELEASE_KEY_PASSWORD")
        }
    }

    buildTypes {
        release {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
            signingConfig = signingConfigs.getByName("release")

            // **DexProtector Configuration:**
            // Tell the plugin where to find your DexProtector XML configuration file.
            extra.set["dexprotector.configFile"] = project.file("dexprotector.xml").path
        }
        debug {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
            // You can specify a different config for debug or omit if not needed
            extra.set["dexprotector.configFile"] = project.file("dexprotector_debug.xml").path
        }
    }

    // ... other settings

}

Note: signingConfig must be specified for all buildTypes where DexProtector is integrated, except debug.

Groovy DSL (app/build.gradle or library/build.gradle)
// app/build.gradle (for Android applications)
// or library/build.gradle (for Android libraries)

apply plugin: 'com.android.application' // or apply plugin: 'com.android.library' for libraries
apply plugin: 'dexprotector' // Apply the DexProtector plugin
// ... other plugins

android {
    namespace 'com.example.yourapp'
    compileSdk 34

    defaultConfig {
        applicationId 'com.example.yourapp'
        minSdk 24
        targetSdk 34
        versionCode 1
        versionName "1.0"
    }

    signingConfigs {
        release {
            storeFile file("config/release.keystore")
            storePassword System.getenv("RELEASE_STORE_PASSWORD")
            keyAlias System.getenv("RELEASE_KEY_ALIAS")
            keyPassword System.getenv("RELEASE_KEY_PASSWORD")
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release

            // **DexProtector Configuration:**
            // Tell the plugin where to find your DexProtector XML configuration file.
            // `projectDir` refers to the current module's directory.
            ext.set("dexprotector.configFile", project.file("dexprotector.xml").path)
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            // You can specify a different config for debug or omit if not needed
            ext.set("dexprotector.configFile", project.file("dexprotector_debug.xml").path)
        }
    }

    // ... other settings
    
}

Note: signingConfig must be specified for all buildTypes where DexProtector is integrated, except debug.

4. Applying variant configurations with product flavors and flavor dimensions

The DexProtector Gradle Plugin offers a configArgs custom property, which allows you to specify configuration options directly within your build script which will override the configuration XML file being applied. This enables you to use productFlavors and flavorDimensions to create variants which build on top of 'base' configuration files, as defined for specific buildTypes. For example:

Kotlin DSL:
buildTypes {
        prod {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
            signingConfig = signingConfigs.getByName("release")
            extra["dexprotector.configFile"] = project.file("dexprotector_base-prod-config.xml").path
        }
        qa {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
            signingConfig = signingConfigs.getByName("qa")
            extra["dexprotector.configFile"] = project.file("dexprotector_base-qa-config.xml").path
        }
        dev {
            isMinifyEnabled = false
        }
    }

    flavorDimensions += "region"
    productFlavors {
        create("US") {
            dimension = "region"
            applicationIdSuffix = ".us"
            versionNameSuffix = ".us"
            // DexProtector config overrides specific to US builds
            extra["dexprotector.configArgs"] = listOf("sha256CertificateFingerprint=4c8f7ab8688778578ed4706c03dd48c977fa407b1f5a33a8f334fd88aa21c86f"
        }
        create("EU") {
            dimension = "region"
            applicationIdSuffix = ".eu"
            versionNameSuffix = ".eu"
            // DexProtector config overrides specific to EU builds
            extra["dexprotector.configArgs"] = listOf("sha256CertificateFingerprint=df54e54c82edcb9d972cb7a9910d2f44546cb875a07a9df4409f5e274fb81e94"
        }
    }
Groovy:
buildTypes {
    prod {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.getByName('release')
        ext['dexprotector.configFile'] = project.file('dexprotector_base-prod-config.xml').path
    }
    qa {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.getByName('qa')
        ext['dexprotector.configFile'] = project.file('dexprotector_base-qa-config.xml').path
    }
    dev {
        minifyEnabled false
    }
}

flavorDimensions += "region"
productFlavors {
    US {
        dimension "US"
        applicationIdSuffix ".us"
        versionNameSuffix ".us"
        // DexProtector config overrides specific to US builds
        ext['dexprotector.configArgs'] = ["sha256CertificateFingerprint=4c8f7ab8688778578ed4706c03dd48c977fa407b1f5a33a8f334fd88aa21c86f"]
    }
    EU {
        dimension "region"
        applicationIdSuffix ".eu"
        versionNameSuffix ".eu"
        // DexProtector config overrides specific to EU builds
        ext['dexprotector.configArgs'] = ["sha256CertificateFingerprint=df54e54c82edcb9d972cb7a9910d2f44546cb875a07a9df4409f5e274fb81e94"]
    }
}

Here you have:

  • 1 flavor dimension
  • 2 product flavors
  • 3 build types

So Gradle will produce 6 (1 x 2 x 3) builds:

USProd

DexProtected with dexprotector_base-prod-config.xml applied, and with sha256CertificateFingerprint element (if defined) overwritten by value 4c8f7ab8688778578ed4706c03dd48c977fa407b1f5a33a8f334fd88aa21c86f

USQa

DexProtected with dexprotector_base-qa-config.xml applied [e.g. with \\\<antiManualInstall\\\>false\\\</antiManualInstall\\\>], and with sha256CertificateFingerprint element (if defined) overwritten by value 4c8f7ab8688778578ed4706c03dd48c977fa407b1f5a33a8f334fd88aa21c86f

US

Not DexProtected, because no DexProtector configuration file specified for that build type

EUProd

DexProtected with dexprotector_base-prod-config.xml applied, and with sha256CertificateFingerprint element (if defined) overwritten by value df54e54c82edcb9d972cb7a9910d2f44546cb875a07a9df4409f5e274fb81e94

EUQa

DexProtected with dexprotector_base-qa-config.xml applied [\\\<antiManualInstall\\\>false\\\</antiManualInstall\\\>], and with sha256CertificateFingerprint element (if defined) overwritten by value df54e54c82edcb9d972cb7a9910d2f44546cb875a07a9df4409f5e274fb81e94

EUDev

Not DexProtected, because no DexProtector configuration file specified for that build type