Skip to content

Instantly share code, notes, and snippets.

@paour
Last active October 5, 2016 12:04
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paour/9189462 to your computer and use it in GitHub Desktop.
Save paour/9189462 to your computer and use it in GitHub Desktop.
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
Copy link
Author

paour 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
Copy link
Author

paour commented Feb 24, 2014

@influenced
Copy link

you are my hero!

@srsudar
Copy link

srsudar 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
Copy link

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

I have none flavors! =D

@martingg88
Copy link

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