Skip to content

Instantly share code, notes, and snippets.

@paour paour/build_extras.gradle
Last active Oct 5, 2016

Embed
What would you like to do?
A simpler and more fool-proof way to handle search providers in Android Gradle builds
def overrideProviderAuthority(packageName, inFile, outFile) {
def xml = new XmlParser().parse(inFile)
xml.findAll{it.name() == 'string'}.each{item ->
if (!item.value().isEmpty() && item.value()[0] instanceof String && item.value()[0].startsWith(".res-auto")) {
item.value()[0] = item.value()[0].replace(".res-auto", packageName)
}
}
saveXML(outFile, xml)
}
def saveXML(pathToFile, xml) {
file(pathToFile).parentFile.mkdirs()
def writer = new FileWriter(pathToFile)
def printer = new XmlNodePrinter(new PrintWriter(writer))
printer.preserveWhitespace = true
printer.print(xml)
}
android.applicationVariants.all { variant ->
def flavor = variant.productFlavors.get(0).name
def buildType = variant.buildType.name
def packageName = variant.mergedFlavor.packageName + (variant.buildType.packageNameSuffix == null ? "" : variant.buildType.packageNameSuffix)
def outFile = "${buildDir}/res-auto-values/${variant.dirName}/values/strings.xml"
// define the strings that need to be auto-replaced in this file, and do NOT define them elsewhere
// make sure your AndroidManifest.xml and searchable.xml reference these resources
// this file should contain string resources; their values will be updated to replace .res-auto with the package name
def inFile = "variants/res-auto-values.xml"
def taskName = "override${flavor.capitalize()}${buildType.capitalize()}Authority"
task(taskName) << {
overrideProviderAuthority(packageName, inFile, outFile)
}
// instead of chnaging resource files from under Gradle, just add a source folder to the resource set
android.sourceSets[variant.name].res.srcDir file(outFile).parentFile.parent
// add in and out files to allow for incremental builds (not hugely important)
tasks[taskName].inputs.file file(inFile)
tasks[taskName].outputs.file file(outFile)
variant.mergeResources.dependsOn tasks[taskName]
}
@paour

This comment has been minimized.

Copy link
Owner Author

commented Feb 24, 2014

I'd been using https://gist.github.com/cmelchior/6988275, but recent versions of the Android gradle plugin and/or IntelliJ have prevented this from working correctly (see the discussion of the referenced gist), and the chosen system caused the build to remerge all resources on each build.

@paour

This comment has been minimized.

Copy link
Owner Author

commented Feb 24, 2014

@influenced

This comment has been minimized.

Copy link

commented Feb 25, 2014

you are my hero!

@srsudar

This comment has been minimized.

Copy link

commented Mar 5, 2014

Great solution. I only have the default build flavor and was getting index out of bounds exceptions. To prevent this I removed the definition of the flavor variable at line 22, which was calling .get(0) on a size 0 list. Similarly in defining the task name I removed the flavor variable: def taskName = "override${buildType.capitalize()}Authority". This when worked like a charm. Only from the command line, incidentally, due to some issues with my Android Studio looking the wrong place for res-auto-values.xml.

EDIT: The issue from inside Android Studio was that the relative paths appeared to be resolved using System.getProperty("user.dir"), which was returning a different directory than that which is returned when calling through the command line. The solution was to give an absolute path to the XMLParser. I replaced the first lines of overrideProviderAuthority with the following:

inFileAbsolute = gradle.startParameter.getProjectDir().getAbsolutePath() + "/" + inFile
def xml = new XmlParser().parse(inFileAbsolute)
@renanfranca

This comment has been minimized.

Copy link

commented May 23, 2014

@srsudar Come here to say thank you very much! =D

I have none flavors! =D

@martingg88

This comment has been minimized.

Copy link

commented Oct 4, 2014

anyone have any idea this script will be executed if I click at "Rebuild Project", but it won't executed when i choose "Debug" app in Android Studio.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.