AndroidManifest.xml dosyamdaki bir BuildConfig değerine nasıl erişebilirim?


137

AndroidManifest.xml dosyasından bir BuildConfig değerine erişmek mümkün müdür?

Build.gradle dosyamda var:

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 dosyalarımda tanımlandı:

# Facebook identifier (app ID)
FACEBOOK_APP_ID=XXXXXXXXXX

Uygulamamda Facebook bağlantısını kullanmak için bu satırı AndroidManifest.xml'e eklemeliyim:

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

@string/applicationIdGradle, şöyle FACEBOOK_APP_IDtanımlanmış BuildConfig alanı ile değiştirmek istiyorum :

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

BuildConfig kullanarak bu mümkün müdür? Değilse, bunu nasıl başarabilirim?

Yanıtlar:


190

değiştirmek

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

ile

resValue "string", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

ardından projenizi yeniden oluşturun (Android Studio -> Derleme -> Projeyi Yeniden Oluştur).

İki komut, proje oluşturma sırasında, hem ilk durumda Java sabitlerinden, ikincisinde Android kaynaklarından oluşan oluşturulan değerler üretir, ancak ikinci yöntem sözdizimi stringkullanılarak erişilebilen bir kaynak değeri oluşturur @string/FACEBOOK_APP_ID. Bu, manifestte ve kodda kullanılabileceği anlamına gelir.


1
Bu kullanıyorum tam kod ama bir sorunla karşı karşıya: Facebook SDK dize bir nedenle tamsayı olarak okur ve sonra bir ClassCastException atar, çünkü Integer String için kullanılamaz. Bu sorunla karşılaşan var mı?
WKS

@WKS Oluşturulan kaynaklar dosyasına bakarsanız, kaynak türü orada beklediğinizle (dize) eşleşiyor mu?
stkent

dizesi:<item name="facebook_app_id" type="string">15233522...</item>
WKS

13
resValue "string" yazdığınızdan ve "String" DEĞİL yazdığınızdan emin olun
keybee

1
Bir boolean değeri kullanmak istiyorsanız, "boolean" yerine resValue "bool" yazdığınızdan emin olun -> tanelikorri.com/tutorial/android/set-variables-in-build-gradle
reavcn

85

Gradle Build Config değerlerine AndroidManifest.xml dosyasından erişmenin başka bir yolu da aşağıdaki gibi yer tutuculardır:

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

ve sonra manifestinizde:

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

Daha fazla ayrıntıyı burada bulabilirsiniz: https://developer.android.com/studio/build/manifest-build-variables.html

(Sadece referans için eski bağlantı: http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger )


2
Bu harika bir çözüm.
BinaryShrub

2
Evet, bu sadece manifesto dizesi enjeksiyonu için güzel bir yöntem!
stkent

2
Java'daki manifestPlaceholders'dan nasıl bir değer elde edersiniz? Bu, hem java kodunda hem de manifest'te kullanılan sabitler için yararlı olacaktır.
Louis CAD

@LouisCAD Sanırım derleme dosyanızda bir değişken tanımlamayı deneyebilir, daha sonra bunu yer tutucunuzu ve (ek olarak) BuildConfig alanını tanımlamak için kullanabilirsiniz, böylece onu kodunuzda kullanabilirsiniz.
GregoryK

1
@LouisCAD Bunu denemedim, ancak aşağıdakileri deneyebilirsiniz: var placeholder = 'yer tutucu' (yeni satır) buildConfigField "String", "PLACEHOLDER_NAME", yer tutucu (yeni satır) manifestPlaceholders = [placeholderName: placholder] (yeni sizin için işe
yarayıp yaramadığını

40

not: resValuedeğeri kullandığınızda dizeler kaynak dosyası tarafından yanlışlıkla geçersiz kılınabilir (örneğin, başka bir dil için)

Eğer Manifestte ve java-kodunda kullanabileceği bir gerçek sabit bir değer elde etmek için, hem kullanabilir manifestPlaceholdersve buildConfigField: örneğin

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

        addConstant("FACEBOOK_APP_ID", "xxxxx")
    }

bildirim dosyasında erişim:

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

Java'dan:

BuildConfig.FACEBOOK_APP_ID

Sabit değerin buildType'a özgü olması gerekiyorsa, yardımcı öğenin ayarlanması addConstantgerekir (mükemmel kapatma semantiği ile çalışmak için), ör.

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
Çalışmıyor, manifest'ten geçersiz uygulama kimliği gösteriyor, ancak
java'dan

Birden fazla sabit eklemeye çalışırsanız bu işe yaramayacağını düşünüyorum!
Greg Ennis

1
@GregEnnis Ayrıca daha fazla sabit benim için iyi çalışır: örneğin ben sadece addConstant()iki kez (farklı constantNamestabii ki) ararım . Hangi hatayı alıyorsun?
TmTron

1
@TmTron hata almazsınız, ancak her çağrıldığında 'manifestPlaceholders' dizisinin tamamını yeniden atarsınız, yalnızca kullanılan son değeri saklarsınız.
Greg Ennis

@GregEnnis kesinlikle haklısın! Test projemde farklı bir kod vardı. Cevabımı zaten güncelledim: +=Operatörü böyle kullanmamız gerekiyormanifestPlaceholders += [...]
TmTron

6

Manifestinizde build.gradle özelliklerine aşağıdaki örnekte olduğu gibi erişin:

Örneğin, build.gradle öğenizde bir "applicationId" özelliğiniz vardır ve buna AndroidManifest'inizden erişmek istersiniz:

resim açıklamasını buraya girin

Android'de "applicationId" dosyasına erişin

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

Benzer şekilde, diğer sabitler için dize kaynakları oluşturabilir ve bunlara kod dosyalarında aşağıdaki gibi basit bir şekilde erişebiliriz:

context.getString(R.string.GCM_SENDER_ID);

mağaza şifremi ve tüm kaydedecek .properties dosyasında facebookAppId: "anotherId ..." tanımlayabilir miyim. Sonra dolaylı olarak AndroidManifest.xml erişilir manifestplaceholders bu erişir. Bunu yapabilir miyim?
Aman Verma

3

@stkent iyidir ancak daha sonra projenizi yeniden oluşturmanız gerektiğini eklemeyi unutur

değiştirmek

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

ile

resValue "string", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

sonra

Android Studio -> Build -> Rebuild Project

Bu android üzerinden erişilebilir dize kaynağı oluşturmak için izin verecektir

R.string.FACEBOOK_APP_ID

1
ProductFlavor_ için bilinmeyen bir özellik 'FACEBOOK_APP_ID'
alınamadı

2

Başka bir seçenek: Lezzet bağımlı tüm değerleri değiştirmek için farklı bir dize kaynak dosyası kullanın:

Adım 1: "src" klasöründe lezzet adınızla yeni bir klasör oluşturun, benim durumum "sahne"

Adım 2: Lezzete bağımlı olan tüm dosyalar için kaynak dosyaları oluşturun, örneğin:

resim açıklamasını buraya girin

Adım 3: Farklı simgeler de kullanıyorum, bu yüzden mipmap klasörlerini de görüyorsunuz. Bu soru için yalnızca "strings.xml" önemlidir. Artık tüm önemli dize kaynaklarının üzerine yazabilirsiniz. Sadece geçersiz kılmak istediklerinizi dahil etmeniz gerekir, diğerleri ana "strings.xml" den kullanılacaktır, Android Studio'da şu şekilde görünecektir:

resim açıklamasını buraya girin

Adım 4: Projenizdeki dize kaynaklarını kullanın ve rahatlayın:

resim açıklamasını buraya girin


İyi bir alternatif, özellikle başka birçok dizeniz varsa, değişken başına ayarlamanız gerekir.
stkent

mağaza şifremi ve tüm kaydedecek .properties dosyasında facebookAppId: "anotherId ..." tanımlayabilir miyim. Sonra dolaylı olarak AndroidManifest.xml erişilir manifestplaceholders bu erişir. Bunu yapabilir miyim?
Aman Verma

0

Aşağıdaki gibi uzun bir değer kullanabilirsiniz

buildConfigField 'uzun', 'FLAVOR_LONG', '11500L'

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.