Using a different manifestPlaceholder for each Build Variant

前端 未结 6 505
长发绾君心
长发绾君心 2020-12-09 03:01

I will start by saying that I am very new to Gradle, so I apologize if this has already been answered.

I\'m working on an Android application that uses an API key to

相关标签:
6条回答
  • 2020-12-09 03:27

    I believe that you need a manifestPlaceHolder to read that value in your Java code, right? If this is the case, you can already read the FLAVOR name in your generated BuildConfig.java. For example, if you define a flavor whose name is smartphone you can access that value using BuildConfig.FLAVOR String; then in your code you can use a simple if (BuildConfig.FLAVOR.equals("smartphone"))...

    But maybe you need to read a sort of configuration of your app, an apiKey. In that case, the best way to go is to create a Class or a string resource for every flavor; this is the link for you.

    0 讨论(0)
  • 2020-12-09 03:31

    Similarly to the accepted answer, you could do it with string resources, if you didn't want to duplicate your manifests.

    For example, if you had two flavors (flavor1 and flavor2) You'd end up w/ the following source sets.

    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
    

    You could then just use a string resource for your key value

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

    One further optimization to keep all your keys in one place is to define them all in strings.xml in your main source set. and then have the flavor/build source sets reference those.

    for example:

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

    then in each of your flavor/build sourceSets, you just reference those keys.

    flavor1Release/res/values/strings.xml

    <resources>
         <string name="apiKey">@string/flavor1ReleaseKey</string>
    </resources>
    
    0 讨论(0)
  • 2020-12-09 03:35

    You may set manifestPlaceholders inside applicationVariants by accessing mergedFlavor for specific applicationVariant.

    android.applicationVariants.all { variant ->
        def mergedFlavor = variant.getMergedFlavor()
        mergedFlavor.manifestPlaceholders = [appPackageId: "myPackageExample"]
    }
    
    0 讨论(0)
  • 2020-12-09 03:35

    I found this great solution in https://azabost.com/android-manifest-placeholders/

    android {
        ...
        buildTypes {
            release {
                ...
                manifestPlaceholders.screenOrientation = "portrait"
            }
            debug {...}
        }
    }
    

    or

    android {
        ...
        flavorDimensions "features"
    
        productFlavors {
    
        paid {
            dimension "features"
            manifestPlaceholders.hostName = "www.paid-example.com"
        }
        free {
            dimension "features"
            manifestPlaceholders.hostName = "www.free-example.com"
        }
    }
    
    0 讨论(0)
  • 2020-12-09 03:50

    What i did is copied current AndroidManifest.xml into app/src/debug

    and changed the key there debug Manifest :

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

    app/src/main Manifest is like :

    <meta-data
            android:name="com.crashlytics.ApiKey"
            android:value="@string/crashlytics_live" />
    
    0 讨论(0)
  • 2020-12-09 03:52

    I would guess that you are referring to Fabric ApiKey? :) I just spent hours trying to do it in a similar way with the placeholders and specifying the ApiKey in the gradle file although it does not seem possible as of com.android.tools.build:gradle:1.3.1. It is possible to specify a placeholder for a specific flavor but not for a flavor AND buildType.

    Just to correct your syntax, the way you would have to do it (if it was possible) would be something like that but manifestPlaceholders are unknown to variants.

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

    What you actually need to do is to keep the key in the AndroidManifest.xml and handle it with multiple manifest file

    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>
    

    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>
    

    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>
    

    The manifestMerger will handle the replacement and you will end up with the proper key in every scenario. I just implemented it successfully. I just hope you were really referring to the Fabric key! :)

    Hope this helps!

    0 讨论(0)
提交回复
热议问题