AndroidManifest.xmlファイルのBuildConfig値にアクセスするにはどうすればよいですか?


137

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_APP_ID 私のgradle.propertiesファイルで定義されています:

# Facebook identifier (app ID)
FACEBOOK_APP_ID=XXXXXXXXXX

アプリでFacebook接続を使用するには、次の行をAndroidManifest.xmlに追加する必要があります。

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

次のように@string/applicationId、gradleでFACEBOOK_APP_ID定義されたBuildConfigフィールドに置き換えます。

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

2つのコマンドはどちらも、プロジェクトのビルド中に生成された値(最初のケースではJava定数、2番目のケースではAndroidリソースで構成される)を生成しますが、2番目のメソッドは構文stringを使用してアクセスできるリソース値を生成し@string/FACEBOOK_APP_IDます。つまり、マニフェストだけでなくコードでも使用できます。


1
これは私が使用している正確なコードですが、問題に直面しています。FacebookSDKは、何らかの理由で文字列を整数として読み取り、次にIntegerをStringにキャストできないため、ClassCastExceptionをスローします。誰かがこの問題に直面しましたか?
WKS 2015

@WKS生成されたリソースファイルを見ると、リソースタイプは期待されるもの(文字列)と一致していますか?
2015

それは文字列です:<item name="facebook_app_id" type="string">15233522...</item>
WKS

13
ことを確認してくださいあなたはresValue「文字列」とNOT resValue「文字列」の書き込み
keybee

1
あなたはブール値を使用したい場合は、必ずresValue「ブール」と入力の代わりにする「ブール」 - > tanelikorri.com/tutorial/android/set-variables-in-build-gradle
reavcn

85

AndroidManifest.xmlからGradle Build Config値にアクセスする別の方法は、次のようなプレースホルダーを使用することです。

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


2
これは素晴らしいソリューションです。
BinaryShrub 2016年

2
ええ、これはマニフェストのみの文字列インジェクションのための素晴らしい方法です!
2016年

2
JavaのmanifestPlaceholdersからどのように値を取得しますか?これは、Javaコードとマニフェストの両方で使用される定数に役立ちます。
Louis CAD

@LouisCADビルドファイルで変数を定義し、それを使用してプレースホルダーと(さらに)BuildConfigフィールドを定義して、コードで使用できるようにすることができます。
GregoryK 2016

1
@LouisCAD私はそれを試しませんでしたが、以下を試すことができます:var placeholder = 'your placeholder'(new line)buildConfigField "String"、 "PLACEHOLDER_NAME"、placeholder(new line)manifestPlaceholders = [placeholderName:placholder](new line)それがあなたのために働くかどうか知って嬉しいでしょう
GregoryK

40

注:resValue値を使用すると、誤って文字列リソースファイル(たとえば、別の言語用)によって上書きされる可能性があります。

マニフェストとjava-codeで使用できる真の定数値を取得するには、manifestPlaceholdersandの両方を使用します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}"/>

Javaから:

BuildConfig.FACEBOOK_APP_ID

定数値がbuildType固有であるaddConstant必要がある場合、ヘルパーを調整する必要があります(グルーヴィーなクロージャーセマンティクスで機能するため)。たとえば、

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

1
動作しませんマニフェストから無効なアプリIDが表示されますが、Javaから設定すると動作します
Brajendra Pandey 2017

複数の定数を追加しようとすると、これはうまくいかないと思います!
グレッグエニス

1
@GregEnnisまた、より多くの定数がうまく機能します。たとえば、addConstant()2回呼び出すだけです(constantNamesもちろん、異なる呼び出しを行います)。どのようなエラーが発生しますか?
TmTron

1
@TmTronではエラーは発生しませんが、 'manifestPlaceholders'配列全体が呼び出されるたびに再割り当てされ、最後に使用された値のみが保存されます。
グレッグエニス2018年

@GregEnnisあなたは絶対にライです!テストプロジェクトで別のコードを使用しました。私はすでに私の答えを更新しました:+=このような演算子を使用する必要があるだけですmanifestPlaceholders += [...]
TmTron

6

次の例のように、マニフェストのbuild.gradleプロパティにアクセスします。

たとえば、build.gradleに「applicationId」というプロパティがあり、AndroidManifestでそれにアクセスしたいとします。

ここに画像の説明を入力してください

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>

同様に、他の定数の文字列リソースを作成し、コードファイルで次のように簡単にアクセスできます。

context.getString(R.string.GCM_SENDER_ID);

.propertiesファイルでfacebookAppId: "anotherId ..."を定義できます。ストアのパスワードとすべてを保存します。次に、AndroidManifest.xmlで間接的にアクセスされるmanifestplaceholdersのそれらにアクセスします。それをしてもいいですか?
Aman Verma

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

ProductFlavor_ ...の不明なプロパティ 'FACEBOOK_APP_ID'を取得できませんでした
f.trajkovski

2

別のオプション:別の文字列リソースファイルを使用して、フレーバーに依存するすべての値を置き換えます。

ステップ1:「src」フォルダーにフレーバーの名前で新しいフォルダーを作成します。私の場合は「stage」です。

ステップ2:たとえば、フレーバーに依存するすべてのファイルのリソースファイルを作成します。

ここに画像の説明を入力してください

ステップ3:別のアイコンも使用しているので、ミップマップフォルダーも表示されます。この質問では、「strings.xml」のみが重要です。これで、すべての重要な文字列リソースを上書きできます。オーバーライドするものだけを含める必要があります。他のすべてはメインの「strings.xml」から使用され、Android Studioでは次のように表示されます。

ここに画像の説明を入力してください

ステップ4:プロジェクトで文字列リソースを使用してリラックスする:

ここに画像の説明を入力してください


特に他の多くの文字列がある場合は、バリアントごとに設定する必要がある優れた代替手段です。
2015年

.propertiesファイルでfacebookAppId: "anotherId ..."を定義できます。ストアのパスワードとすべてを保存します。次に、AndroidManifest.xmlで間接的にアクセスされるmanifestplaceholdersのそれらにアクセスします。それをしてもいいですか?
Aman Verma

0

以下のように長い値を使用できます

buildConfigField 'long'、 'FLAVOR_LONG'、 '11500L'

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.