ProGuard writes the mapping file under the build directory of the project. Under normal circumstances all files and directories under the build dirs are excluded from version control. That is a bit of an issue if you want to be able to save that file with every release build. I always forget to this manually. So, let’s do that at build time with Gradle and while we are at it, we might as well rename our apk file, so we don’t have to do that manually either.

Here is the relevant code to put in our build.gradle file:


import java.util.regex.Matcher
import java.util.regex.Pattern

buildTypes {
        release {
        debuggable false
        minifyEnabled true
        proguardFiles 'proguard.cfg'

        // Rename the apk file and copy the ProGuard mapping file to the root of the project
        applicationVariants.all { variant ->
            if (variant.getBuildType().name.equals("release")) {
                def formattedDate = new Date().format('yyyyMMddHHmmss')
                def projectName = ""
                variant.outputs.all { output ->
                        def fullName = output.outputFile.name
                        projectName = fullName.substring(0, fullName.indexOf('-'))
                        // ${variant.name} has the value of "paidRelease"
                        outputFileName = new File((String) output.outputFile.parent, (String) outputFileName.replace(".apk", "-v${variant.versionName}-${formattedDate}.apk"))
                    }
                def mappingFile = "${rootDir}/${projectName}/build/outputs/mapping/${getCurrentFlavor()}/release/mapping.txt"
                println("mappingFile:  ${mappingFile}")
                if (variant.getBuildType().isMinifyEnabled()) {
                    variant.assemble.doLast {
                        copy {
                            from "${mappingFile}"
                            into "${rootDir}"
                            rename { String fileName ->
                                "mapping-${variant.name}.txt"
                            }
                        }
                    }
                }
            }
        }
    }

    debug {
        debuggable true
    }
}

def getCurrentFlavor() {
    Gradle gradle = getGradle()
    String  tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
    Pattern pattern;

    if( tskReqStr.contains( "assemble" ) )
        pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
    else
        pattern = Pattern.compile("generate(\\w+)(Release|Debug)")

    Matcher matcher = pattern.matcher( tskReqStr )

    if( matcher.find() )
        return matcher.group(1).toLowerCase()
    else {
        println "NO MATCH FOUND"
        return "";
    }
}

The above code was updated for the new Android Studio 3.0 and Gradle 3.0.

The new Gradle introduces some changes and the output.outputFile is now a read only property. So, you cannot change it starting with Gradle 3. You will get the following error:

“Cannot set the value of read-only property ‘outputFile’ for ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=release, filters=[]}}…”

Here are the changes:

old:


variant.outputs.each { output ->
                    def fullName = output.outputFile.name
                    projectName = fullName.substring(0, fullName.indexOf('-'))
                    // ${variant.name} has the value of "paidRelease"
                    output.outputFile = new File((String) output.outputFile.parent, (String) output.outputFile.name.replace(".apk", "-v${variant.versionName}-${formattedDate}.apk"))
                }

new:


variant.outputs.all { output ->
                        def fullName = output.outputFile.name
                        projectName = fullName.substring(0, fullName.indexOf('-'))
                        // ${variant.name} has the value of "paidRelease"
                        outputFileName = new File((String) output.outputFile.parent, (String) outputFileName.replace(".apk", "-v${variant.versionName}-${formattedDate}.apk"))
                    }
Gradle – Automatically rename the .apk file and copy the ProGuard mapping.txt file
Tagged on:             

Leave a Reply

Your email address will not be published. Required fields are marked *

*