Как получить доступ к значению BuildConfig в моем файле AndroidManifest.xml?

137

Можно ли получить доступ к значению BuildConfig из AndroidManifest.xml?

В моем файле build.gradle у меня есть:

defaultConfig {
    applicationId "com.compagny.product"
    minSdkVersion 16
    targetSdkVersion 21
    versionCode 1
    versionName "1.0"

    // Facebook app id
    buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID
}

FACEBOOK_APP_ID определяется в моих файлах gradle.properties:

# Facebook identifier (app ID)
FACEBOOK_APP_ID=XXXXXXXXXX

Чтобы использовать Facebook Connect в моем приложении, я должен добавить эту строку в мой AndroidManifest.xml:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/applicationId"/> 

Я хочу заменить @string/applicationIdна поле FACEBOOK_APP_IDBuildConfig, определенное в gradle, вот так:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="FACEBOOK_APP_ID"/> 

Возможно ли это с помощью BuildConfig? Если нет, как я могу этого достичь?

Энтони
источник

Ответы:

190

замещать

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

с участием

resValue "string", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

затем пересоберите свой проект (Android Studio -> Build -> Rebuild Project).

Обе команды выдают сгенерированные значения - состоящие из констант Java в первом случае и ресурсов Android во втором - во время сборки проекта, но второй метод сгенерирует stringзначение ресурса, к которому можно получить доступ с использованием @string/FACEBOOK_APP_IDсинтаксиса. Это означает, что его можно использовать как в манифесте, так и в коде.

stkent
источник
1
Это именно тот код, который я использую, но я столкнулся с проблемой: Facebook SDK по какой-то причине читает строку как целое число, а затем выдает исключение ClassCastException, потому что Integer не может быть приведен к String. Кто-нибудь сталкивался с этой проблемой?
WKS
@WKS Если вы посмотрите на сгенерированный файл ресурсов, соответствует ли тип ресурса тому, что вы ожидаете (строка)?
15:00
это строка:<item name="facebook_app_id" type="string">15233522...</item>
WKS
13
убедитесь, что вы пишете resValue "string", а НЕ resValue "String"
keybee
1
Если вы хотите использовать логическое значение, убедитесь, что вы набрали resValue "bool" вместо "boolean" -> tanelikorri.com/tutorial/android/set-variables-in-build-gradle
reavcn
85

Еще один способ получить доступ к значениям Gradle Build Config из вашего AndroidManifest.xml - использовать заполнители следующим образом:

android {
    defaultConfig {
        manifestPlaceholders = [ facebookAppId:"someId..."]
    }
    productFlavors {
        flavor1 {
        }
        flavor2 {
            manifestPlaceholders = [ facebookAppId:"anotherId..." ]
        }
    }
}

а затем в вашем манифесте:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="${facebookAppId}"/> 

Подробности смотрите здесь: https://developer.android.com/studio/build/manifest-build-variables.html.

(Старая ссылка только для справки: http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger )

GregoryK
источник
2
Это отличное решение.
BinaryShrub
2
Да, это хороший метод для вставки строки только для манифеста!
stkent
2
Как бы вы получить значение из manifestPlaceholder в Java? Это было бы полезно для констант, используемых как в коде Java, так и в манифесте.
Луи CAD
@LouisCAD Я полагаю, что вы можете попытаться определить переменную в вашем файле сборки, а затем использовать ее для определения вашего заполнителя и (дополнительно) поля BuildConfig, чтобы вы могли использовать его в своем коде.
GregoryK
1
@LouisCAD Я не пробовал этого, но вы можете попробовать следующее: var placeholder = 'your placeholder' (новая строка) buildConfigField "String", "PLACEHOLDER_NAME", placeholder (новая строка) manifestPlaceholder = [placeholderName: placholder] (new линия) Буду рад узнать, работает ли он у вас
GregoryK
40

примечание: при использовании resValueзначение может быть случайно переопределено файлом ресурсов строки (например, для другого языка)

Чтобы получить истинное постоянное значение, которое вы можете использовать в манифесте и в java-коде, используйте оба manifestPlaceholdersи buildConfigField: например

android {
    defaultConfig {
        def addConstant = {constantName, constantValue ->
            manifestPlaceholders += [ (constantName):constantValue]
            buildConfigField "String", "${constantName}", "\"${constantValue}\""
        }

        addConstant("FACEBOOK_APP_ID", "xxxxx")
    }

доступ в файле манифеста:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="${FACEBOOK_APP_ID}"/>

из Явы:

BuildConfig.FACEBOOK_APP_ID

Если значение константы должно быть специфичным для buildType, помощник addConstantдолжен быть настроен (для работы с семантикой Groovy замыкания), например,

buildTypes {
    def addConstantTo = {target, constantName, constantValue ->
        target.manifestPlaceholders += [ (constantName):constantValue]
        target.buildConfigField "String", "${constantName}", "\"${constantValue}\""
    }
    debug {
        addConstantTo(owner,"FACEBOOK_APP_ID", "xxxxx-debug")
    }
    release {
        addConstantTo(owner,"FACEBOOK_APP_ID", "xxxxx-release")
    }
TmTron
источник
1
Не работает, показывает неверный идентификатор приложения, из манифеста, но когда установлено из Java, то это работает
Brajendra Pandey
Я думаю, что это не сработает, если вы попытаетесь добавить более одной константы!
Грег Эннис,
1
@GregEnnis Также у меня отлично работает больше констант: например, я просто звоню addConstant()дважды (с разным, constantNamesконечно). Какая у вас ошибка?
TmTron
1
@TmTron вы не получаете ошибку, но вы переопределяете весь массив 'manifestPlaceholder' каждый раз, когда он вызывается, сохраняя только последнее использованное значение.
Грег Эннис
@GregEnnis ты абсолютно прав! У меня был другой код в моем тестовом проекте. Я уже обновил свой ответ: нам просто нужно использовать такой +=операторmanifestPlaceholders += [...]
TmTron
6

Откройте свойства build.gradle в своем манифесте, как показано в следующем примере:

Например, у вас есть свойство «applicationId» в вашем build.gradle, и вы хотите получить к нему доступ в вашем AndroidManifest:

введите описание изображения здесь

Откройте «applicationId» в AndroidManifest:

<receiver
        android:name="com.google.android.gms.gcm.GcmReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="${applicationId}" />
        </intent-filter>
    </receiver>

Точно так же мы можем создавать строковые ресурсы для других констант и обращаться к ним в файлах кода так же просто, как:

context.getString(R.string.GCM_SENDER_ID);
Виней
источник
Могу ли я определить facebookAppId: "anotherId ..." в файле .properties, где я буду сохранять свой пароль магазина и все. Затем я получаю доступ к тем в манифестозаменителях, которые косвенно будут доступны в AndroidManifest.xml. Могу ли я сделать это?
Аман Верма
3

@stkent - это хорошо, но забывает добавить, что вам нужно потом перестроить свой проект

замещать

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

с участием

resValue "string", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

затем

Android Studio -> Build -> Rebuild Project

Это позволит Android генерировать строковый ресурс, доступный через

R.string.FACEBOOK_APP_ID
FOO
источник
Не удалось получить неизвестное свойство 'FACEBOOK_APP_ID' для ProductFlavor_ ...
f.trajkovski
2

Другой вариант: использовать другой файл строковых ресурсов для замены всех зависимых от вкуса значений:

Шаг 1: Создайте новую папку в папке «src» с названием вашего вкуса, в моем случае «stage»

Шаг 2: Создайте файлы ресурсов для всех файлов, которые зависят от разновидности, например:

введите описание изображения здесь

Шаг 3: Я также использую различные значки, поэтому вы также видите папки mipmap. Для этой очереди важен только "strings.xml". Теперь вы можете перезаписать все важные строковые ресурсы. Вам нужно только включить те, которые вы хотите переопределить, все остальные будут использоваться из основного "strings.xml", он будет отображаться в Android Studio следующим образом:

введите описание изображения здесь

Шаг 4: Используйте строковые ресурсы в вашем проекте и расслабьтесь:

введите описание изображения здесь

Бьорн Кехель
источник
Хорошая альтернатива, особенно если у вас есть много других строк, которые вы должны установить для каждого варианта.
stkent
Могу ли я определить facebookAppId: "anotherId ..." в файле .properties, где я буду сохранять свой пароль магазина и все. Затем я получаю доступ к тем в манифестозаменителях, которые косвенно будут доступны в AndroidManifest.xml. Могу ли я сделать это?
Аман Верма
0

Вы можете использовать длинное значение, как показано ниже

buildConfigField 'long', 'FLAVOR_LONG', '11500L'

Кейур Тумар
источник