为每个Build Variant使用不同的manifestPlaceholder

时间:2015-07-16 17:54:51

标签: android gradle android-gradle

我首先要说的是我对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" ]
            }    
        }
    }
}

到目前为止,manifestPlaceholders语句的工作范围非常简单,但我不知道如何从 productFlavors buildType >阻止我可以将其用作条件。

7 个答案:

答案 0 :(得分:21)

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

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

}

答案 1 :(得分:6)

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

例如,如果您有两种口味(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

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

<?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>

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

例如:

<resources>
    <string name="flavor1ReleaseKey">flavor1ReleaseKey</string>
    <string name="flavor1DebugKey">flavor1DebugKey</string>
    <string name="flavor2ReleaseKey">flavor2ReleaseKey</string>
    <string name="flavor2DebugKey">flavor2DebugKey</string>
</resources>

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

flavor1Release / RES /值/ strings.xml中

<resources>
     <string name="apiKey">@string/flavor1ReleaseKey</string>
</resources>

答案 2 :(得分:2)

我在https://azabost.com/android-manifest-placeholders/

中找到了一个很好的解决方案
android {
    ...
    buildTypes {
        release {
            ...
            manifestPlaceholders.screenOrientation = "portrait"
        }
        debug {...}
    }
}

android {
    ...
    flavorDimensions "features"

    productFlavors {

    paid {
        dimension "features"
        manifestPlaceholders.hostName = "www.paid-example.com"
    }
    free {
        dimension "features"
        manifestPlaceholders.hostName = "www.free-example.com"
    }
}

答案 3 :(得分:1)

我相信你需要一个manifestPlaceHolder来读取Java代码中的那个值,对吧?如果是这种情况,您可以在生成的BuildConfig.java中读取FLAVOR名称。例如,如果您定义名称为 smartphone 的flavor,则可以使用BuildConfig.FLAVOR String访问该值;然后在您的代码中,您可以使用简单的if (BuildConfig.FLAVOR.equals("smartphone"))...

但也许你需要阅读你的应用程序的一种配置,一个apiKey。在这种情况下,最好的方法是为每种风格创建一个Class或一个字符串资源;这是你的link

答案 4 :(得分:1)

你不需要重复的文件
构建.gradle

productFlavors {
    prod {
        applicationId "com.example.prod"
        dimension "mode"
        manifestPlaceholders = [hostName:"some String"]
    }
    dev {
        applicationId "com.example.dev"
        dimension "mode"
        manifestPlaceholders = [hostName:"some String"]
    }

说明使用“${hostName}”。下面的例子

<meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="${hostName}" />

答案 5 :(得分:0)

我所做的是将当前{"user_name":"test","password":"testing"} function validate() { var jsdata; $.ajax({ type: "GET", url:"jsonv.json", dataType: "json", data: JSON.stringify({ user_name: $("#input").val(), password: $("#input1").val() }), success: function(response) { jsdata=response; var un = document.loginscreen.uname.value; var pw = document.loginscreen.psw.value; if ((un == jsdata.user_name) && (pw == jsdata.password)) { alert(jsdata.user_name+'//'+jsdata.password); //window.location = "file:///C:/Users/KS5034674/Desktop/Gagile/WebContent/homescreen.html"; return true; } else { console.log("login Failed"); } }, error: function(response) { console.log(response); } }); } 复制到AndroidManifest.xml

并更改了密钥那里调试Manifest:

app/src/debug

<meta-data android:name="com.crashlytics.ApiKey" tools:replace="android:value" android:value="@string/crashlytics_debug" /> 清单就像:

app/src/main

答案 6 :(得分:0)

作为对@Eric 帖子的补充,对于 AGP 版本 com.android.tools.build:gradle:4.x,此代码片段

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" ]
        }    
    }
}

应该更新为

androidComponents {
    onVariants(selector().withBuildType("debug")) {
        manifestPlaceholders.apiKey = "DEBUG_KEY"
    }

    onVariants(selector().withBuildType("release")) {
        if(flavorName.equals("someFlavor")) 
            manifestPlaceholders.apiKey = "RELEASE_KEY_1"
        else 
            manifestPlaceholders.apiKey = "RELEASE_KEY_2"
    }
}