Come posso accedere a un valore BuildConfig nel mio file AndroidManifest.xml?


137

È possibile accedere a un valore BuildConfig da AndroidManifest.xml?

Nel mio file build.gradle ho:

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 è definito nei miei file gradle.properties:

# Facebook identifier (app ID)
FACEBOOK_APP_ID=XXXXXXXXXX

Per utilizzare Facebook Connect nella mia app, devo aggiungere questa riga al mio AndroidManifest.xml:

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

Voglio sostituire @string/applicationIdcon il campo BuildConfig FACEBOOK_APP_IDdefinito in gradle, in questo modo:

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

È possibile usare BuildConfig? In caso contrario, come posso raggiungere questo obiettivo?

Risposte:


190

Sostituire

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

con

resValue "string", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

quindi ricostruisci il tuo progetto (Android Studio -> Build -> Rebuild Project).

Entrambi i comandi producono valori generati - costituiti da costanti Java nel primo caso e risorse Android nel secondo - durante le build del progetto, ma il secondo metodo genererà un stringvalore di risorsa a cui è possibile accedere utilizzando la @string/FACEBOOK_APP_IDsintassi. Ciò significa che può essere utilizzato sia nel manifest che nel codice.


1
Questo è il codice esatto che sto usando ma sto affrontando un problema: Facebook SDK legge la stringa come numero intero per qualche motivo e quindi genera ClassCastException perché Integer non può essere trasmesso su String. Qualcuno ha affrontato questo problema?
WKS,

@WKS Se guardi il file di risorse generato, il tipo di risorsa corrisponde a quello che ti aspetti (stringa) lì?
Stkent,

è stringa:<item name="facebook_app_id" type="string">15233522...</item>
WKS,

13
assicurati di scrivere resValue "stringa" e NON resValue "stringa"
keybee

1
Se si desidera utilizzare un valore booleano, assicurarsi di digitare resValue "boolean" anziché "boolean" -> tanelikorri.com/tutorial/android/set-variables-in-build-gradle
reavcn

85

Un altro modo per accedere ai valori Gradle Build Config dal tuo AndroidManifest.xml è tramite segnaposto come questo:

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

e poi nel tuo manifest:

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

Vedi maggiori dettagli qui: https://developer.android.com/studio/build/manifest-build-variables.html

(Vecchio link solo per riferimento: http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger )


2
Questa è un'ottima soluzione
BinaryShrub

2
Sì, questo è un bel metodo per l'iniezione di stringhe solo manifest!
Stkent,

2
Come otterresti un valore da manifestPlaceholders in java? Ciò sarebbe utile per le costanti utilizzate sia nel codice Java che in manifest.
Louis CAD,

@LouisCAD Suppongo che tu possa provare a definire una variabile nel tuo file di build, quindi usarlo per definire il tuo segnaposto e (in aggiunta) il campo BuildConfig, in modo da poterlo usare nel tuo codice.
GregoryK,

1
@LouisCAD Non l'ho provato, ma puoi provare quanto segue: var placeholder = 'your placeholder' (new line) buildConfigField "String", "PLACEHOLDER_NAME", placeholder (new line) manifestPlaceholders = [placeholderName: placholder] (nuovo linea) Sarebbe felice di sapere se funziona per te
GregoryK,

40

nota: quando si utilizza resValueil valore può essere accidentalmente sovrascritto dal file di risorse delle stringhe (ad es. per un'altra lingua)

Per ottenere un vero valore costante che puoi usare nel manifest e nel codice java, usa entrambi manifestPlaceholderse buildConfigField: es

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

        addConstant("FACEBOOK_APP_ID", "xxxxx")
    }

accesso al file manifest:

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

da java:

BuildConfig.FACEBOOK_APP_ID

Se il valore costante deve essere specifico per il tipo di build, l'helper addConstantdeve essere ottimizzato (per lavorare con semantica di chiusura groovy), ad es.

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
Non funziona, mostra un ID app non valido, da manifest, ma quando impostato da Java allora funziona
Brajendra Pandey,

Penso che questo non funzionerà se provi ad aggiungere più di una costante!
Greg Ennis,

1
@GregEnnis Anche più costanti funzionano bene per me: ad esempio, chiamo solo addConstant()due volte (con diversi constantNamesovviamente). Che errore ricevi?
TmTron,

1
@TmTron non viene visualizzato un errore, ma si riassegna l'intero array 'manifestPlaceholders' ogni volta che viene chiamato, memorizzando solo l'ultimo valore utilizzato.
Greg Ennis,

@GregEnnis sei assolutamente giusto! Ho avuto un codice diverso nel mio progetto di test. Ho già aggiornato la mia risposta: dobbiamo solo usare l' +=operatore in questo modomanifestPlaceholders += [...]
TmTron

6

Accedi alle proprietà build.gradle nel tuo manifest come nell'esempio seguente:

Ad esempio hai una proprietà "applicationId" nel tuo build.gradle e vuoi accedervi nel tuo AndroidManifest:

inserisci qui la descrizione dell'immagine

Accedi a "applicationId" in 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>

Allo stesso modo, possiamo creare risorse di stringa per altre costanti e accedervi in ​​file di codice semplici come:

context.getString(R.string.GCM_SENDER_ID);

posso definire facebookAppId: "anotherId ..." nel file .properties dove vorrei salvare la password del mio negozio e tutto il resto. Quindi accedo a quelli in manifestplaceholders ai quali si accede indirettamente in AndroidManifest.xml. Posso farlo?
Aman Verma,

3

@stkent è buono ma dimentica di aggiungere che è necessario ricostruire il progetto in seguito

Sostituire

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

con

resValue "string", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

poi

Android Studio -> Build -> Rebuild Project

Ciò consentirà ad Android di generare la risorsa stringa accessibile tramite

R.string.FACEBOOK_APP_ID

Impossibile ottenere la proprietà sconosciuta "FACEBOOK_APP_ID" per ProductFlavor_ ...
f.trajkovski,

2

Un'altra opzione: utilizzare un file di risorse stringa diverso per sostituire tutti i valori dipendenti dal sapore:

Passaggio 1: crea una nuova cartella nella cartella "src" con il nome del tuo sapore, nel mio caso "stage"

Passaggio 2: creare file di risorse per tutti i file che dipendono dal sapore, ad esempio:

inserisci qui la descrizione dell'immagine

Passo 3: sto anche usando icone diverse, quindi vedi anche le cartelle mipmap. Per questa domanda, è importante solo "strings.xml". Ora puoi sovrascrivere tutte le risorse di stringa importanti. Devi solo includere quelli che vuoi sovrascrivere, tutti gli altri verranno utilizzati dal principale "strings.xml", verrà visualizzato in Android Studio in questo modo:

inserisci qui la descrizione dell'immagine

Passaggio 4: utilizzare le risorse di stringa nel progetto e rilassarsi:

inserisci qui la descrizione dell'immagine


Una buona alternativa, soprattutto se hai molte altre stringhe che devi impostare per variante.
Stkent,

posso definire facebookAppId: "anotherId ..." nel file .properties dove vorrei salvare la password del mio negozio e tutto il resto. Quindi accedo a quelli in manifestplaceholders ai quali si accede indirettamente in AndroidManifest.xml. Posso farlo?
Aman Verma,

0

È possibile utilizzare il valore lungo come di seguito

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.