如何访问AndroidManifest.xml文件中的BuildConfig值?

如何访问AndroidManifest.xml文件中的BuildConfig值?,android,android-gradle-plugin,android-xml,android-facebook,Android,Android Gradle Plugin,Android Xml,Android Facebook,是否可以从AndroidManifest.xml访问BuildConfig值 在我的build.gradle文件中,我有: defaultConfig { applicationId "com.compagny.product" minSdkVersion 16 targetSdkVersion 21 versionCode 1 versionName "1.0" // Facebook app id buildConfigField "

是否可以从AndroidManifest.xml访问BuildConfig值

在我的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\u APP\u ID
在my 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"/> 
使用BuildConfig可以吗?如果没有,我如何才能做到这一点?

替换

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID
buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

然后(Android Studio->构建->重建项目)


在项目构建期间,这两个命令都会生成生成的值(第一种情况下由Java常量组成,第二种情况下由Android资源组成),但第二种方法将生成一个
string
资源值,可以使用
@string/FACEBOOK\u APP\u ID
语法访问该值。这意味着它可以在清单和代码中使用。

另一个选项:使用不同的字符串资源文件替换所有依赖于味道的值:

步骤1: 在“src”文件夹中创建一个新文件夹,名称为您的flavor,im my case“stage”

步骤2: 为依赖于样式的所有文件创建资源文件 例如:

步骤3: 我还使用了不同的图标,因此您也可以看到mipmap文件夹。对于这个问题,只有“strings.xml”是重要的。现在您可以覆盖所有重要的字符串资源。您只需要包含要覆盖的内容,所有其他内容都将从主“strings.xml”中使用,它将在Android Studio中显示如下:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="FACEBOOK_APP_ID"/> 
android {
    defaultConfig {
        manifestPlaceholders = [ facebookAppId:"someId..."]
    }
    productFlavors {
        flavor1 {
        }
        flavor2 {
            manifestPlaceholders = [ facebookAppId:"anotherId..." ]
        }
    }
}

步骤4: 使用项目中的字符串资源并放松:


从AndroidManifest.xml访问Gradle构建配置值的另一种方法是通过以下占位符:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="FACEBOOK_APP_ID"/> 
android {
    defaultConfig {
        manifestPlaceholders = [ facebookAppId:"someId..."]
    }
    productFlavors {
        flavor1 {
        }
        flavor2 {
            manifestPlaceholders = [ facebookAppId:"anotherId..." ]
        }
    }
}
然后在你的舱单上:

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

请参阅此处的更多详细信息:


(旧链接仅供参考:)

访问清单中的build.gradle属性,如下例所示:

例如,您在build.gradle中有一个属性“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>

访问AndroidManifest中的“applicationId”:

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

@stkent很好,但忘了补充一点,即您需要在以后重建项目

替换

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID
buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

然后

这将允许android生成可通过访问的字符串资源

R.string.FACEBOOK_APP_ID

注意:使用
resValue
时,字符串资源文件可能会意外覆盖该值(例如,对于其他语言)

要获得可在清单和java代码中使用的真正常量值,请同时使用
manifestplaceholder
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}"/>
如果常量值需要特定于buildType,则需要调整helper
addConstant
(以使用groovy闭包语义),例如


您可以使用长值,如下所示



buildConfigField'long'、'FLAVOR_long'、'11500L'

这正是我正在使用的代码,但我面临一个问题:Facebook SDK出于某种原因将字符串读取为整数,然后抛出ClassCastException,因为整数无法转换为字符串。有人遇到过这个问题吗?@W.K.S如果您查看生成的资源文件,资源类型是否与您期望的(字符串)匹配?它是字符串:
15233522…
确保您编写的是resValue“string”而不是resValue“string”。如果您想使用布尔值,请确保键入resValue“bool”而不是“boolean”->这是一个很好的选择,尤其是当您需要为每个变量设置许多其他字符串时。我是否可以在.properties文件中定义facebookAppId:“anotherId…”,在该文件中我将保存我的存储密码和所有内容。然后访问ManifestPlaceholder中的内容,这些内容将在AndroidManifest.xml中间接访问。我可以这样做吗?这是一个很好的解决方案。是的,这是一个很好的只用于清单字符串注入的方法!在java中,如何从manifest占位符中获取值?这对java代码和清单中使用的常量都很有用。@LouisCAD我想您可以尝试在生成文件中定义一个变量,然后用它定义占位符和(另外)BuildConfig字段,这样您就可以在代码中使用它。@LouisCAD我没有尝试过,但您可以尝试以下操作:var placeholder='your placeholder'(新行)buildConfigField“String”,“placeholder_NAME”,placeholder(新行)manifestPlaceholders=[placeholder NAME:placeholder](新行)很高兴知道它是否适用于您不适用它显示了无效的应用程序id,从清单,但是当从java设置时,如果你试图添加多个常量,我认为这是行不通的@GregEnnis还有更多的常量对我来说很好:例如,我只需调用
addConstant()
两次(当然是使用不同的
constantNames
)。您得到了什么错误?@TmTron您没有得到错误,但每次调用时您都会重新分配整个“manifestPlaceholders”数组,只存储最后使用的值。@GregEnnis您完全正确!我的测试项目中有不同的代码。我已经更新了我的答案:我们只需要像这样使用
+=
操作符
manifestPlaceholders+=[…]
我可以在.properties文件中定义facebookAppId:“anotherId…”,在该文件中我将保存我的商店密码和所有内容。然后访问ManifestPlaceholder中的内容,这些内容将在AndroidManifest.xml中间接访问。我可以这样做吗?无法获取ProductFlavor的未知属性“FACEBOOK\u APP\u ID”。。。
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")
    }