Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle "manifest requires a placeholder substitution" error but manifestPlaceholders supplies a value

I'm trying to perform substitution within the AndroidManifest.xml file from the build.gradle android extension but am getting this error:

AndroidManifest.xml:89:16 Error:
    Attribute uses-library#com.company.platform.${encoding}@name at AndroidManifest.xml:89:16 requires a placeholder substitution but no value for <encoding> is provided.
/Users/Company/Desktop/Checkout/android/Project/app/src/main/AndroidManifest.xml:0:0 Error:
    Validation failed, exiting
:app:processDebugManifest FAILED

This is a snippet of the manifest file:

...
     </receiver>
   <uses-library android:name="com.company.platform.${encoding}" />
</application>
...

And this is a snipped of the build.gradle:

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"
    defaultConfig {
        applicationId "com.company.app"
        minSdkVersion 23
        targetSdkVersion 23
        versionName cityVersion
        setProperty("archivesBaseName", "City_$versionName")
        manifestPlaceholders = [encoding: "some value"]
        manifestPlaceholders = [version: cityVersion]
    }

I've also tried adding the manifestPlaceholders in the buildTypes i.e.

buildTypes {
    release {
        minifyEnabled true
        shrinkResources true
        manifestPlaceholders = [encoding: deviceEncoding]
        manifestPlaceholders = [version: cityIDVersion]
   }
    debug {
        manifestPlaceholders = [encoding: deviceEncoding]
        manifestPlaceholders = [version: cityIDVersion]
    }

}

But I still get the same error.

Why is there an error about it requiring a placeholder substitution when one is provided for in the manifestPlaceholders?

like image 276
Gruntcakes Avatar asked May 21 '16 21:05

Gruntcakes


3 Answers

You need to just add to the array. You are replacing it. Do this:

manifestPlaceholders = [encoding: "some value", version: cityVersion]

By declaring manifestPlaceholders twice for the same flavor/build type, your are replacing the previous one. After the previous one got replaced, your build failed because the property no longer exists.

like image 191
jesobremonte Avatar answered Oct 09 '22 17:10

jesobremonte


For those of you running into manifest merger / manifest injection issues due to manifestPlaceholders defined in your libraries manifest, the issue is coming from the fact that you need to define a value for the manifestPlaceholders in your libraries manifest. That value is not getting overridden when you inject your real value in the consuming application. To get around this, you should only define those manifestPlaceholders values for debug builds in your library.

Like so:

android.buildTypes.debug.manifestPlaceholders = [
    authScheme: 'clientAppReplaces', authHost: 'clientAppReplaces'
]

By doing this you will be able to build your library. While also letting the client application supply the correct values for the manifestPlaceholders. Allowing your library to do all that heavy lifting it should. This is possible because libraries build as release builds (unless defined otherwise).

Client app build.gradle example:

defaultConfig {
    applicationId "com.app.manifestPlaceholders"
    minSdkVersion 16
    targetSdkVersion 27
    versionCode project.ext.versionCode
    versionName project.ext.versionName

    manifestPlaceholders = [authScheme: 'customSchemeValue', authHost: 'hostValue']
}
like image 38
Sakiboy Avatar answered Oct 09 '22 15:10

Sakiboy


this

 manifestPlaceholders = [encoding: "some value"]
 manifestPlaceholders = [version: cityVersion]

should be like this

 manifestPlaceholders = [encoding: "some value"]
 manifestPlaceholders += [version: cityVersion]
like image 1
Salman Qadami Avatar answered Oct 09 '22 17:10

Salman Qadami