Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Gradle Read App Name from strings.xml

I am trying to rename my APK files for each build variant to include the application name, versionName, versionCode and build number when present. So far I have everything working except the application name.

I want to use the same value that the AndroidManifest.xml file uses for android:label. This comes from a string resource @string/app_name. I have seen the ability to replace the resource values by using:

resValue "string", "app_name", "Some new value"

But I would just like to read this value and use it to name my APK file.

android.applicationVariants.all { variant ->
    variant.outputs.each { output ->
        renameApk(variant, output)
    }
}

def renameApk(variant, output) {
    def apkPath = output.outputFile.parent
    def baseName = project.archivesBaseName

    baseName += "-${variant.buildType.name}"

    // add version name and version code
    baseName += "-v${variant.mergedFlavor.versionName}-${variant.mergedFlavor.versionCode}"

    // if built on jenkins ci, add jenkins build number:
    def buildNumber = System.getenv('BUILD_NUMBER')
    if (buildNumber && buildNumber.size() > 0) {
        baseName += "-b${buildNumber}"
    }

    // if the variant will not be zipAligned, specify that
    if (!output.zipAlign) {
        baseName += '-unaligned'
    }

    // set the output file
    output.outputFile = new File(apkPath, "${baseName}.apk");
}
like image 894
steji113 Avatar asked Jun 29 '15 18:06

steji113


2 Answers

I don't see any method in Android Plugin docs for accessing resources, so here is the code you can use to find your app's name by searching resources:

def getAppName() {
    def stringsFile = android.sourceSets.main.res.sourceFiles.find { it.name.equals 'strings.xml' }
    return new XmlParser().parse(stringsFile).string.find { [email protected] 'app_name' }.text()
}

BUT I completely agree with @Samuil Yanovski in that it is not worth it - better hardcode a string. I don't think it will slow down building process, but it is just unnecessary.

like image 127
Yaroslav Avatar answered Oct 01 '22 09:10

Yaroslav


I don't think this can be done easily. Resource resolution is done on the mobile device to accommodate for things like screen orientation, localization and so on. The Gradle build system has no way of knowing which locale to use for example. If you insist on getting the value from the resources, you can open the specific strings.xml file you'd like to use, parse the XML and get the value yourself. In my opinion this is a huge overkill and would be pretty slow and ugly.

App name is not changed often, so I would be comfortable with having it hardcoded (especially since the apk file name is not visible to the end user, so even if mistakes happen, the impact would be minimal). If you are working on a white label application and have to support dynamic app name, extracting the value to the gradle.properties file (or some other type of configuration file, you are using) should be a better option rather than using the app's resources.

like image 40
Samuil Yanovski Avatar answered Oct 01 '22 07:10

Samuil Yanovski