2010-10-21 10 views
22

Estoy buscando optimizar la generación de APK ligeramente diferentes de la misma aplicación de Android, la única diferencia es el servidor http API que está usando (dev/staging/prod) .Cree versiones múltiples (prueba/prod) de APK Android en Eclipse

Idealmente, me gustaría que mi Eclipse compilara 2 APK, uno con el servidor de prod y otro con el dev.

Estoy incluso bien con tener 2 configuraciones de ejecución, pero no he podido averiguar cómo pasar parámetros a la aplicación y leerlos desde el código.

Quiero apuntar a 1,5, por cierto, y me gustaría usar las herramientas de construcción automática de Eclipse, así que estoy buscando la solución más genérica.

Gracias.

+0

posible duplicado de [Android - múltiples versiones personalizadas de la misma aplicación] (http: // stackoverflow .com/questions/1222302/android - multiple-custom-versions-of-the-same-app) – EboMike

+0

Ninguna de las soluciones se integra muy bien con Eclipse hasta donde yo sé. De hecho, no estoy seguro de por qué una tarea tan simple parece tan complicada.No para iniciar una guerra de llama, pero he echado un vistazo al desarrollador de iPhone de nuestro desarrollador de iPhone, y es muy trivial pasarle parámetros a su aplicación desde el exterior. Esto me pone triste. –

+0

Sé cómo hacer esto con maven-android-plugin, en realidad es bastante fácil. sin embargo, requiere atar su aplicación con maven, además, parece haber algunas incompatibilidades con la última versión de Android SDK (r14 y r15) en maven-android-plugin/m2e-android, probablemente no es lo que quiere. – yorkw

Respuesta

0

Para pasar parámetros, siempre puedes crear un archivo en el sistema de directorios de Android y tener tu código leéndolo.

+1

Pero, ¿cómo se transfiere el parámetro de nombre de archivo al código? Si puedo pasar un nombre de archivo, también puedo pasar una URL del servidor; la pregunta es cómo. –

1

No es realmente lo que quiere:

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

entonces usted podría golpear un dev/puesta en escena del servidor si la aplicación se firma con una clave de depuración, y la producción con un certificado de aptitud.

+0

Esto sigue construyendo 1 archivo: quiero que Eclipse construya 2 (o N) archivos y cree múltiples configuraciones para construir fácilmente etapas, desarrolladores, etc. –

4

Mover todo lo que el código para un proyecto de biblioteca ve http://developer.android.com/guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject

A continuación, crear proyectos separados en Eclipse para la prueba y la producción de cada uno con un nombre de paquete único. A continuación, puede usar el nombre del paquete para distinguir entre versiones.

Algo así como:

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

Esto puede parecer demasiado difícil para la gestión de diferentes puntos finales http sino que hará que el código sea más manejable. También puede hacer cosas útiles, como:

  • bandera de la versión de prueba con un icono de aplicación diferente
  • plazo de prueba y producción versiones lado a lado en un dispositivo

Todo esto se puede hacer en Eclipse sin usar y herramientas de terceros.

+0

Eso me suena como una pesadilla para el control de versiones, con un nombre de paquete diferente en el parte superior de cada archivo. ¿Me equivoco? –

+0

No hay ningún problema con el control de versiones. El nombre del paquete se establece una vez en el manifiesto y todo el código permanece en el proyecto de la biblioteca. – railwayparade

+0

En mi código, el nombre del paquete está presente en cada archivo de Java. –

9

Creo que usar script de compilación ant sería la solución más fácil. Eclipse es compatible con la creación de ant, para que pueda ejecutar el comando ant en eclipse.

Puede resolver su problema con ant como este.

  1. prepare dos xml archivo de recursos android.
  2. construir un paquete con recursos # 1
  3. recursos de sobreescritura # 1 con el contenido del recurso # 2
  4. construir otro paquete

XML sería así:

recurso # 1:

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

res ource # 2:

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

y el guión de hormigas serían así:

<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

Ahora parece que estamos llegando a algún lado. ¿Puedes dar más instrucciones sobre cómo configurar esto en Eclipse? –

+0

vea esto: [Ant support] (http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.user%2Fconcepts%2Fconcepts-antsupport.htm) - 1. create nuevo archivo de compilación de ant/2. abrir ant view en eclipse/3. agregar su compilación ant a la vista (arrastrar y soltar)/4. ejecutarlo. – kingori

+0

tenga cuidado: android necesita hormiga 1.8 o posterior. eclipse ha incorporado hormiga, pero su versión es 1.7. deberías instalar la hormiga manualmente, y luego configurar tu hormiga binaria como hormiga predeterminada binaria en propiedades de eclipse. – kingori

0

En mi caso, yo sólo quería cambiar algunos valores en strings.xml entre las diferentes versiones.

En primer lugar tengo que cargar la biblioteca ant-contrib, para definir la tarea for bucle:

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

pongo mi lista de configuraciones, config.names, en un archivo properties:

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

y definir un objetivo build-all, que recorre el config.names:

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

La definición de un directorio personalizado resources para cada uno, ahorrando el nombre del directorio en el config.resources propiedad:

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

eliminarlo, y copiar los recursos globales de res en él:

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

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

Cambio - a / en el nombre de la configuración, para que sea una ruta en el parámetro de la URL:

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

Ejecutar una transformación XSLT para modificar el archivo 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> 

Esta es la hoja de estilo XSLT que utilizo:

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

Y de vuelta a custom_rules.xml donde luego extraer el app_version del original (sin modificar) res/values/strings.xml:

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

Y utilizar la tarea antcall a llamar a la debug construcción:

<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 dos valores de propiedad modificados:

  • resource.absolute.dir le indica a debug usar mi res directorio modificado, que se define en la propiedad config.resources arriba;
  • out.final.file indica que debe producir una APK con un nombre diferente, incluido el nombre de la configuración (por ejemplo, student-testing) y el número de versión extraído de strings.xml.

Y luego, finalmente, puedo ejecutar ant build-all desde la línea de comandos y construir los cuatro objetivos. Un poco más de la escritura, justo antes del final del objetivo build-all, muestra los archivos APK compilado juntos para referencia:

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