Modtion logo
Modtion
android

Android : Save Secret Key in Gradle Properties and Output Name

Android : Save Secret Key in Gradle Properties and Output Name

Secure Your Private Key

The api key and host URL are sensitive data and must be kept confidential to the general public outside the company and developers. Even though you have used deobfuscate and proguard, there is still a possibility of getting secret data when the APK is reverse-engineered. one method to overcome this is to save it in gradle.properties and create code to call it in build.gradle.kts.

app/gradle.properties

...
android.nonTransitiveRClass=true

# add your key here
API_DEVELOPMENT="http://api.development.com"
API_PRODUCTION="http://api.development.com"

GMAPS_API="************"

app/build.gradle.kts

android {

    ...

    flavorDimensions += "env"
    productFlavors {
        create("development") {
            dimension = "env"

            buildConfigField("String", "API_URL", project.properties["API_DEVELOPMENT"].toString())
        }
        create("production") {
            dimension = "env"

            buildConfigField("String", "API_URL", project.properties["API_PRODUCTION"].toString())
        }
    }
}

If you are confused by the code above, you can read the blog again about build types https://www.modtion.id/posts/android-build-types-and-flavors

Dynamic String Value

Apart from buildConfig which can be used in all Kotlin code according to the specified flavors, we can create dynamic string values ​​in the string.xml file like the code below and string name must be same with resValue

<resources>
    <string name="app_name">PolarLoc</string>
</resources>
android {

    ...

    flavorDimensions += "env"
    productFlavors {
        create("development") {
            dimension = "env"

            buildConfigField("String", "API_URL", project.properties["API_DEVELOPMENT"].toString())

            resValue("string", "app_name", "Modtion Development)
        }
        create("production") {
            dimension = "env"

            buildConfigField("String", "API_URL", project.properties["API_PRODUCTION"].toString())

            resValue("string", "app_name", "Modtion")
        }
    }
}

Dynamic Manifest

We can also create dynamic text specifically for use in the AndroidManifest.xml file. One use is to set icons, labels and so on

android {

    ...

    flavorDimensions += "env"
    productFlavors {
        create("development") {
            dimension = "env"

            buildConfigField("String", "API_URL", project.properties["API_DEVELOPMENT"].toString())

            resValue("string", "app_name", "Modtion Development")

            manifestPlaceholders["AppName"] = "Modtion Development"
        }
        create("production") {
            dimension = "env"

            buildConfigField("String", "API_URL", project.properties["API_PRODUCTION"].toString())

            resValue("string", "app_name", "Modtion")

            manifestPlaceholders["AppName"] = "Modtion Development"
        }
    }
}

Output Name APK

the apk names of the build results are always the same, namely debug_app.apk and release_app.apk . This will be confusing if we work with many developers, QA and other divisions. This happens because it will be difficult to distinguish the latest apk, build type, flavor, version and so on. if rewriting the apk name will be tedious and QA reporting if there is a bug in the apk will be difficult. Therefore, it is better to change the output name by entering some data such as build time, flavor, build type and version name. here is the code how to change the apk output name.

<manifest>
    <application
        ...
        android:label="${AppName}"
        ...
        >
    </application>
</manifest>
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
import java.text.SimpleDateFormat
import java.util.*

android {
    applicationVariants.all {
        val outputFileName = "modtion" +
                "_${flavorName}" +
                "_${buildType.name}" +
                "_v${this.versionName}" +
                "_${SimpleDateFormat("ddMMyy_HHmm", Locale.US).format(Date())}.apk"
        outputs.all {
            val output = this as? BaseVariantOutputImpl
            output?.outputFileName = outputFileName
        }
    }
}

the result of this change is modtion_development_debug_v1.0.0_281123_0146.apk