2010-10-21 4 views
22

Sto cercando di ottimizzare la generazione di APK leggermente diversi della stessa app Android, con l'unica differenza del server API HTTP che sta utilizzando (dev/staging/prod) .Crea versioni multiple (test/prod) di APK Android in Eclipse

Idealmente, vorrei solo che il mio Eclipse costruisse 2 APK, uno con il server prod e uno con il dev.

Sono persino a posto con 2 configurazioni di esecuzione, ma non sono stato in grado di capire come passare i parametri all'app e leggerli dal codice.

Voglio targetizzare 1.5, BTW e mi piacerebbe utilizzare gli strumenti di autocostruzione di Eclipse, quindi sto cercando la soluzione più generica.

Grazie.

+0

possibile duplicato di [Android - più versioni personalizzate del stessa applicazione] (http: // StackOverflow .com/questions/1222302/android - versioni multiple-custom-della-stessa-app) – EboMike

+0

Nessuna delle soluzioni si integra bene con Eclipse per quanto posso dire. Sono in realtà abbastanza perplesso sul motivo per cui un compito così semplice sembra così complicato.Non per iniziare un flamewar, ma ho dato un'occhiata allo sviluppatore iPhone del nostro sviluppatore iPhone, ed è piuttosto banale passare i parametri alla tua applicazione dall'esterno. Questo mi rende triste. –

+0

So come farlo con maven-android-plugin, in realtà piuttosto facile. tuttavia, è necessario associare l'applicazione a Maven, inoltre, sembra che ci siano alcune incompatibilità con l'ultimo SDK di Android (r14 e r15) in maven-android-plugin/m2e-android, probabilmente non è ciò che si desidera. – yorkw

risposta

0

Per passare i parametri, è sempre possibile creare un file nel sistema di directory di Android e fare in modo che il codice lo legga da esso.

+1

Ma come si passa il parametro del nome file al codice? Se riesco a passare un nome di file, posso passare anche un URL del server - la domanda è come. –

1

Il suo non è ciò che si vuole:

private static Boolean isSignedWithDebugKey = null; 
    protected boolean signedWithDebug() { 
     if(isSignedWithDebugKey == null) { 
      PackageManager pm = getPackageManager(); 
      try { 
       PackageInfo pi = pm.getPackageInfo(getPackageName(), 0); 
       isSignedWithDebugKey = (pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 
      } 
      catch(NameNotFoundException nnfe) { 
       nnfe.printStackTrace(); 
       isSignedWithDebugKey = false; 
      } 
     } 

     return isSignedWithDebugKey; 
    } 

si potrebbe quindi colpire un dev/staging server se l'applicazione è firmato con una chiave di debug, e la produzione con un certificato di rilascio.

+0

Questo ancora crea 1 file - Voglio Eclipse per creare 2 (o N) file e creare configurazioni multiple per creare facilmente staging, dev, ecc. –

4

Sposta tutto quello che il codice a un progetto di libreria vedi http://developer.android.com/guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject

Poi creare progetti separati in Eclipse per il test e la produzione di ciascuno con un nome unico pacchetto. È quindi possibile utilizzare il nome del pacchetto per distinguere tra versioni.

Qualcosa di simile:

public static boolean isProductionVersion(){ 
    return context.getPackageName().toLowerCase().contains("production"); 
} 

Questo può sembrare eccessivo per la gestione di diversi punti finali http ma renderà il codice più gestibile. È anche possibile fare cose utili come:

  • bandiera la versione di prova con un'icona diversa applicazione
  • run versioni di test e di produzione fianco a fianco su un unico dispositivo

Tutto questo può essere fatto in Eclipse senza utilizzare strumenti di terze parti.

+0

Mi sembra un incubo per il controllo di versione per me, con un nome di pacchetto diverso al in cima a ciascun file. Ho sbagliato? –

+0

Nessun problema con il controllo della versione. Il nome del pacchetto viene impostato una volta nel manifest e tutto il codice rimane nel progetto della libreria. – railwayparade

+0

Nel mio codice, il nome del pacchetto è presente in ogni file Java. –

9

Penso che usare lo script di formica sarebbe la soluzione più semplice. Eclipse supporta la generazione di formiche, quindi puoi eseguire il comando ant in eclipse.

Puoi risolvere il tuo problema con formiche come questo.

  1. preparare due file di risorse Android xml.
  2. costruire un pacchetto con risorsa # 1
  3. risorsa sovrascrittura # 1 con contenuto di risorsa # 2
  4. costruire un altro pacchetto

XML sarebbe come questo:

risorsa # 1:

<resources> 
    <string name="target">dev</string> 
</resources> 

res ource # 2:

<resources> 
    <string name="target">staging</string> 
</resources> 

e script ant sarebbe come questo:

<project> 
    <target name="build_all"> 
    <copy file="res1.xml" to="res/values/target.xml"/> 
    <ant antfile="build.xml" target="debug"/> 
    <copy file="res2.xml" to="res/values/target.xml"/> 
    <ant antfile="build.xml" target="debug"/> 
    </target> 
</project> 
+0

Ora sembra che stiamo arrivando da qualche parte. Puoi fornire ulteriori istruzioni su come configurarlo in Eclipse? –

+0

vedere questo: [Supporto Ant] (http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.user%2Fconcepts%2Fconcepts-antsupport.htm) - 1. creare nuovo file build ant/2. apri formica vista in eclipse/3. aggiungi la tua formica alla vista (drag & drop)/4. eseguila. – kingori

+0

fai attenzione: Android ha bisogno di ant 1.8 o successivo. eclipse ha costruito nel form, ma la sua versione è 1.7. dovresti installare manualmente il form e quindi impostare il tuo ant-binary come ant-default binary nelle proprietà di eclipse. – kingori

0

Nel mio caso ho voluto solo cambiare alcuni valori in strings.xml tra le diverse versioni.

prima devo caricare la libreria ant-contrib, per definire il compito for ciclo:

<taskdef resource="net/sf/antcontrib/antcontrib.properties"> 
    <classpath> 
     <pathelement location="lib/ant-contrib-1.0b5-SNAPSHOT.jar" /> 
    </classpath> 
</taskdef> 

ho messo il mio elenco di configurazioni, config.names, in un file properties:

config.url.root=http://projectserver.aptivate.org/ 
config.names=student-production, teacher-production, student-testing, teacher-testing 

e definire a target build-all, che scorre su config.names:

<target name="build-all"> 
    <for param="config.name" trim="true" list="${config.names}"> 
     <sequential> 

Definizione di una directory personalizzata resources per ciascuno di essi, salvare il nome della directory nella config.resources proprietà:

<var name="config.resources" unset="true" /> 
<property name="config.resources" value="bin/res-generated/@{config.name}" /> 

eliminarlo, e copiare le risorse globali da res in esso:

<delete dir="${config.resources}" /> 

<copy todir="${config.resources}"> 
    <fileset dir="res"/> 
</copy> 

Change - a / nel nome di configurazione, per renderlo un percorso nel parametro URL:

<var name="config.path" unset="true" /> 
<propertyregex property="config.path" 
    input="@{config.name}" regexp="-" 
    replace="/" casesensitive="true" /> 

Eseguire una trasformazione XSLT per modificare il file strings.xml:

<xslt in="res/values/strings.xml" 
    out="${config.resources}/values/strings.xml" 
    style="ant/create_xml_configs.xslt" 
    force="true"> 
    <param name="config.url.root" expression="${config.url.root}" /> 
    <param name="config.name" expression="@{config.name}" /> 
    <param name="config.path" expression="${config.path}" /> 
</xslt> 

Questo è il foglio di stile XSLT che uso:

<?xml version="1.0" encoding="ISO-8859-1"?> 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
      <xsl:param name="config.url.root" /> 
      <xsl:param name="config.name" /> 
      <xsl:param name="config.path" /> 

      <!-- http://my.safaribooksonline.com/book/xml/9780596527211/creating-output/xslt-id-4.6 --> 
      <xsl:template match="/"> 
        <!-- 
        This file is automatically generated from res/values/strings.xml 
        by ant/custom_rules.xml using ant/create_xml_configs.xslt. 
        Do not modify it by hand; your changes will be overwritten. 
        --> 
        <xsl:apply-templates select="*"/> 
      </xsl:template> 

      <xsl:template match="*"> 
        <xsl:copy> 
          <xsl:for-each select="@*"> 
            <xsl:copy/> 
          </xsl:for-each> 
          <xsl:apply-templates/> 
        </xsl:copy> 
      </xsl:template> 

      <!-- the value of update_server_url must end with a slash! --> 
      <xsl:template match="string[@name='update_server_url']/text()"> 
        <xsl:value-of select="$config.url.root" /><xsl:value-of select="$config.path" />/ 
      </xsl:template> 

      <xsl:template match="string[@name='app_version']/text()"> 
        <xsl:value-of select="." />-<xsl:value-of select="$config.name" /> 
      </xsl:template> 
    </xsl:stylesheet> 

e di nuovo a custom_rules.xml dove ho quindi estrarre il app_version dall'originale (non modificata) res/values/strings.xml:

<xpath input="res/values/strings.xml" 
    expression="/resources/string[@name='app_version']" 
    output="resources.strings.app_version" /> 

E utilizzare l'attività antcall per chiamare il debug costruzione:

<antcall target="debug"> 
    <param name="resource.absolute.dir" value="${config.resources}" /> 
    <param name="out.final.file" value="${out.absolute.dir}/${ant.project.name}-${resources.strings.app_version}[email protected]{config.name}.apk" /> 
</antcall> 

con due valori di proprietà modificati:

  • resource.absolute.dir dice il bersaglio debug di utilizzare il mio modificato res directory, definito nella proprietà config.resources sopra;
  • out.final.file indica di generare un APK con un nome diverso, incluso il nome di configurazione (ad esempio student-testing) e il numero di versione estratto da strings.xml.

E quindi, finalmente, è possibile eseguire ant build-all dalla riga di comando e creare tutti e quattro i target. Un po 'più di script, poco prima della fine del build-all bersaglio, elenca i file APK compilato insieme per riferimento:

<echo message="Output packages:" /> 
<for param="config.name" trim="true" list="${config.names}"> 
    <sequential> 
     <echo message="${out.absolute.dir}/${ant.project.name}-${resources.strings.app_version}[email protected]{config.name}.apk" /> 
    </sequential> 
</for>