I have my own Gradle plugin where I'd like to add a task which would take launcher icons from main folder and output icons for each build type/flavor folder tinted with different colors depending on user's extension configuration.
I've added the task for application variant:
variant.registerResGeneratingTask(tintTask, new File("${project.buildDir}/generated/res/${variant.name}"))
Then in the task I perform the operation described above. Until here everything is fine - the sources are generated and the folder is marked as a resource folder.
The problem is when I try to create a build and the flow hits the mergeXXXResources task (in this case xxx == debug).
At this point I get an exception comparing the mipmap-[dpi]-v4/ic_launcher in the main/res with those in generated/res/debug.
For example:
Execution failed for task ':app:mergeDebugResources'.
[mipmap-hdpi-v4/ic_launcher] /{proj_location}/android_example/app/src/main/res/mipmap-hdpi/ic_launcher.png
[mipmap-hdpi-v4/ic_launcher] /{proj_location}/android_example/app/build/generated/res/debug/mipmap-hdpi/ic_launcher.png:
Error: Duplicate resources
I tried different locations for my output files, but I don't believe it makes any difference. I expected the resource merger to be able to identify generated resources and parse them in the final output, but obviously I'm doing something horribly wrong.
I've tried using the Transform API instead, but perhaps because of scarce documentation and my lack of understanding my attempts weren't very successful (I couldn't locate resource files in a fashion similar to the way I've located java files during transform operation).
I'm looking for either a piece of advice on how to resolve my current problem, or an alternative approach which would perform the task I've initially set out to achieve.
EDIT: on request, code for my task action:
@TaskAction
def convertLauncherIcons() {
def android = project.extensions.getByType(AppExtension)
File outputDir = new File("${project.buildDir}/generated/tintLaunchIcons/res/${taskVariant.name}")
android.sourceSets.each {
if ("main".equals(it.name)) {
it.res.srcDirs.each { dirIt ->
dirIt.absoluteFile.list().each { resDir ->
if (resDir.startsWith("mipmap-")) {
def relIconPath = "${resDir}/ic_launcher.png"
File launcherFile = new File(dirIt.absolutePath, relIconPath);
if (launcherFile.exists()) {
BufferedImage img = ImageIO.read(launcherFile);
/* IMAGE MANIPULATION HERE */
File outputFile = new File(outputDir, relIconPath);
if (!outputFile.exists()) {
File parent = outputFile.getParentFile();
if (!parent.exists() && !parent.mkdirs()) {
throw new IllegalStateException("Couldn't create dir: " + parent);
}
outputFile.createNewFile();
}
println "writing file ${outputFile.canonicalPath}"
ImageIO.write(img, "png", outputFile);
} ...
app/build/intermediates/incremental/mergeDebugResources,app/build/intermediates/res/merged/debugandapp/build/intermediates/blame/res/debug. But this is executed only after the task registered as resGeneratingTask.variant.registerResGeneratingTaskto the main directory and let gradle take care of merging it into the build. Let me know if it helps :)./app/src/debug/res/mipmap-[density]i/ic_launcher.pngbut I'm still getting the same error. In act of desperation I've tried overriding the resource in "main" (though obviously this is not what I ultimately want to do), but that enraged the build process even further and I got the "duplicate" error about all kinds of resources I haven't even touched.