为每个Build Variant使用不同的manifestPlaceholder

Sto*_*oph 25 android gradle android-gradle-plugin

我首先要说的是我对Gradle很新,所以如果已经回答,我会道歉.

我正在开发一个使用API​​密钥访问第三方工具的Android应用程序.根据应用程序的风格构建类型,需要使用不同的API密钥.

这是我正在尝试做的基本概述:

android {
    defaultConfig {
        manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]
    }

    buildTypes{
        debug{
            // Some debug setup
        }
        release{
            // Some release setup
        }
    }

    productFlavors {
        // List of flavor options
    }
    productFlavors.all{ flavor->
        if (flavor.name.equals("someFlavor")) {
            if (buildType.equals("release")) {
                manifestPlaceholders = [ apiKey:"RELEASE_KEY_1" ]
            } else {
                manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]
            }
        } else {
            if (buildType.equals("release")) {
                manifestPlaceholders = [ apiKey:"RELEASE_KEY_2" ]
            } else {
                manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]
            }    
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,该manifestPlaceholders语句在一个非常简单的情况下工作,但我不知道如何从productFlavors块中引用buildType,以便我可以将它用作条件.

Ali*_*Ali 25

您可以通过访问特定applicationVariant的mergedFlavor在applicationVariants中设置manifestPlaceholders.

android.applicationVariants.all { variant ->
    def mergedFlavor = variant.getMergedFlavor()
    mergedFlavor.manifestPlaceholders = [appPackageId: "myPackage1"]
Run Code Online (Sandbox Code Playgroud)

}

  • 这应该是公认的答案。为了区分变体,您可以执行以下操作:```android.applicationVariants.all {variant-> def mergedFlavor = variant.getMergedFlavor()if(variant.buildType.name.equals(“ debug”)&& variant.flavorName.equals (“ demo”)){mergedFlavor.manifestPlaceholders = [appPackageId:“ myPackage1”]}}``` (3认同)
  • 这应该是接受的答案,因为它允许您在gradle配置中读取属性文件(应该包含您的密钥),这些文件不应该检入SCM,然后在清单占位符中设置密钥.通过将密钥放入资源文件,您可以将其公开给访问您的仓库的任何人. (2认同)

Eri*_*lle 13

我猜你是指Fabric ApiKey?:)我花了好几个小时尝试以类似的方式使用占位符并在gradle文件中指定ApiKey,尽管它似乎不可能com.android.tools.build:gradle:1.3.1.可以为特定flavor指定占位符,但不能为flavor AND buildType指定占位符.

只是为了纠正你的语法,你必须这样做(如果可能的话)会是这样的,但manifestPlaceholders对于变体是未知的.

applicationVariants.all{ variant->
    if (variant.productFlavors.get(0).name.equals("someFlavor")) {
        if (variant.buildType.name.equals("release")) {
            manifestPlaceholders = [ apiKey:"RELEASE_KEY_1" ]
        } else {
            manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]
        }
    } else {
        if (variant.buildType.name.equals("release")) {
            manifestPlaceholders = [ apiKey:"RELEASE_KEY_2" ]
        } else {
            manifestPlaceholders = [ apiKey:"DEBUG_KEY" ]
        }    
    }
}
Run Code Online (Sandbox Code Playgroud)

您实际需要做的是保持密钥AndroidManifest.xml并使用多个清单文件处理它

SRC/AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">    
    <application>    
        <meta-data
            android:name="io.fabric.ApiKey"
            android:value="DEBUG_KEY" tools:replace="android:value"/>
    </application>    
</manifest>
Run Code Online (Sandbox Code Playgroud)

SRC/someFlavorRelease/AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">    
    <application>    
        <meta-data
            android:name="io.fabric.ApiKey"
            android:value="RELEASE_KEY_1" tools:replace="android:value"/>
    </application>    
</manifest>
Run Code Online (Sandbox Code Playgroud)

SRC/someOtherFlavorRelease/AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">    
    <application>    
        <meta-data
            android:name="io.fabric.ApiKey"
            android:value="RELEASE_KEY_2" tools:replace="android:value"/>
    </application>    
</manifest>
Run Code Online (Sandbox Code Playgroud)

manifestMerger将处理替换,您将在每个场景中使用正确的密钥.我刚刚成功实现了它.我只是希望你真的指的是Fabric键!:)

希望这可以帮助!

  • 您可以使用`variant.mergedFlavor.manifestPlaceholders =`更新值,而无需为每个变体创建`AndroidManifest.xml`,如@Morten Holmgaard答案所示。 (3认同)

Nel*_*rez 7

与接受的答案类似,如果您不想复制清单,则可以使用字符串资源执行此操作.

例如,如果您有两种口味(flavor1和flavor2),您最终会得到以下源集.

app/
  src/
    main/
      res/
         values/strings.xml
    flavor1Release/
      res/
         values/strings.xml
    flavor1Debug/
      res/
         values/strings.xml

    flavor2Release/
       res/
         values/strings.xml
    flavor2Debug/
       res/
         values/strings.xml
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用字符串资源作为键值

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">    
    <application>    
        <meta-data
            android:name="io.fabric.ApiKey"
            android:value="@string/apiKey" tools:replace="android:value"/>
    </application>    
</manifest>
Run Code Online (Sandbox Code Playgroud)

将所有密钥保存在一个位置的另一个优化是在主源集的strings.xml中定义它们.然后让flavor/build source设置引用那些.

例如:

<resources>
    <string name="flavor1ReleaseKey">flavor1ReleaseKey</string>
    <string name="flavor1DebugKey">flavor1DebugKey</string>
    <string name="flavor2ReleaseKey">flavor2ReleaseKey</string>
    <string name="flavor2DebugKey">flavor2DebugKey</string>
</resources>
Run Code Online (Sandbox Code Playgroud)

然后在每个flavor/build sourceSets中,您只需引用这些键.

flavor1Release/RES /值/ strings.xml中

<resources>
     <string name="apiKey">@string/flavor1ReleaseKey</string>
</resources>
Run Code Online (Sandbox Code Playgroud)


Lui*_*dez 6

我在https://azabost.com/android-manifest-placeholders/找到了这个很好的解决方案

android {
    ...
    buildTypes {
        release {
            ...
            manifestPlaceholders.screenOrientation = "portrait"
        }
        debug {...}
    }
}
Run Code Online (Sandbox Code Playgroud)

或者

android {
    ...
    flavorDimensions "features"

    productFlavors {

    paid {
        dimension "features"
        manifestPlaceholders.hostName = "www.paid-example.com"
    }
    free {
        dimension "features"
        manifestPlaceholders.hostName = "www.free-example.com"
    }
}
Run Code Online (Sandbox Code Playgroud)