Использование другого manifestPlaceholder для каждого варианта сборки

Начну с того, что я очень новичок в Gradle, поэтому приношу свои извинения, если на это уже был дан ответ.

Я работаю над приложением Android, которое использует ключ API для доступа к стороннему инструменту. Необходимо использовать другой ключ 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 работает в очень простом случае, но я не знаю, как ссылаться на buildType из блока productFlavors, чтобы Я могу использовать его как условное.

Ответ 1

Я бы предположил, что вы имеете в виду Fabric ApiKey?:) Я просто потратил часы, пытаясь сделать это аналогичным образом с заполнителями и указав ApiKey в файле gradle, хотя это не представляется возможным с com.android.tools.build:gradle:1.3.1. Можно указать местозаполнитель для конкретного вкуса, но не для аромата И 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" ]
        }    
    }
}

Что вам действительно нужно сделать, так это сохранить ключ в 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>

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>

Функция manifestMerger будет обрабатывать замену, и в каждом случае вы получите правильный ключ. Я просто успешно его реализовал. Я просто надеюсь, что вы действительно имели в виду ключ Fabric!:)

Надеюсь, это поможет!

Ответ 2

Вы можете установить manifestPlaceholders внутри applicationVariants, обратившись к объединенномуFlavor для конкретного applicationVariant.

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

}

Ответ 3

Подобно принятому ответу, вы можете сделать это со строковыми ресурсами, если не хотите дублировать свои манифесты.

Например, если у вас было два аромата (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 в вашем основном исходном наборе. а затем источник источника/источника сборки ссылается на них.

например:

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

то в каждом из ваших источников /build sourceSets вы просто ссылаетесь на эти ключи.

flavor1Release/RES/значения/strings.xml

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

Ответ 4

Я считаю, что вам нужно, чтобы manifestPlaceHolder читал это значение в вашем коде Java, правильно? Если это так, вы уже можете прочитать имя FLAVOR в созданном BuildConfig.java. Например, если вы определяете аромат, имя которого является смартфоном, вы можете получить доступ к этому значению с помощью BuildConfig.FLAVOR String; то в вашем коде вы можете использовать простой if (BuildConfig.FLAVOR.equals("smartphone"))...

Но, возможно, вам нужно прочитать какую-то конфигурацию вашего приложения, apiKey. В этом случае лучший способ - создать класс или строковый ресурс для каждого аромата; это ссылка для вас.

Ответ 5

То, что я сделал, копирует текущий AndroidManifest.xml в app/src/debug

и изменил ключ там debug Manifest:

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

app/src/main Манифест выглядит как:

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