Создайте несколько (тестовых / prod) версий Android APK в Eclipse

Я хочу оптимизировать создание несколько разных APK одного и того же приложения для Android, с той лишь разницей, что он использует сервер http-API (dev / staging / prod).

В идеале я просто хочу, чтобы мой Eclipse построил 2 APK, один с prod-сервером и один с dev.

Я даже в порядке с конфигурацией 2 Run, но мне не удалось выяснить, как передать параметры в приложение и прочитать их из кода.

Я хочу настроить таргетинг на 1.5, BTW, и я бы хотел использовать инструменты автоматической сборки Eclipse, поэтому я ищу наиболее общее решение.

Спасибо.

Solutions Collecting From Web of "Создайте несколько (тестовых / prod) версий Android APK в Eclipse"

Я думаю, что использование скрипта ant build будет самым простым решением. Eclipse поддерживает ant build, поэтому вы можете запускать команду ant в eclipse.

Вы можете решить свою проблему с муравьем вроде этого.

  1. Подготовьте два файла ресурсов xml android.
  2. Создать пакет с ресурсом # 1
  3. Перезаписать ресурс # 1 с содержимым ресурса # 2
  4. Создать еще один пакет

Xml будет выглядеть так:

Ресурс # 1:

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

Ресурс № 2:

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

И скрипт ant будет выглядеть так:

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

Переместите весь код в проект библиотеки, см. http://developer.android.com/guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject

Затем создайте отдельные проекты в eclipse для тестирования и производства с уникальным именем пакета. Затем вы можете использовать имя пакета для различения версий.

Что-то вроде:

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

Это может показаться излишним для управления различными конечными точками http, но это сделает код более управляемым. Вы также можете делать такие полезные вещи, как:

  • Флаг тестовой версии с другим значком приложения
  • Запускать тестовые и производственные версии бок о бок на одном устройстве

Все это можно сделать в eclipse без использования сторонних инструментов.

Это не то, что вы хотите:

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

Затем вы можете попасть на сервер dev / staging, если приложение подписано с помощью отладочного ключа, и выпуск с сертификатом выпуска.

Для передачи параметров вы всегда можете создать файл в системе каталогов Android и прочитать его код.

В моем случае я просто хотел изменить несколько значений в strings.xml между разными версиями.

Сначала мне нужно загрузить библиотеку ant-contrib , чтобы определить задачу for loop:

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

Я поместил список конфигураций, config.names , в файл properties :

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

И определите цель build-all цели, которая перебирает config.names :

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

Определение каталога настраиваемых resources для каждого из них, сохранение имени каталога в свойстве config.resources :

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

Удалите его и скопируйте глобальные ресурсы из res в него:

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

Изменить - на / в имени конфигурации, чтобы указать путь в параметре URL:

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

Запустите XSLT-преобразование, чтобы изменить файл 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> 

Это таблица стилей XSLT, которую я использую:

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

И вернемся к custom_rules.xml где затем извлекаю app_version из исходного (немодифицированного) res/values/strings.xml :

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

И используйте задачу antcall для вызова сборки debug :

 <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}-@{config.name}.apk" /> </antcall> 

С двумя измененными значениями свойств:

  • resource.absolute.dir сообщает цели debug использовать мой измененный каталог res , определенный в свойстве config.resources выше;
  • out.final.file сообщает, что он создает APK с другим именем, включая имя конфигурации (например, student-testing ) и номер версии, извлеченный из strings.xml .

И затем, наконец, я могу запустить ant build-all из командной строки и собрать все четыре цели. Немного больше сценария, как раз перед окончанием цели build-all , перечисляет скомпилированные файлы APK для ссылки:

 <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}-@{config.name}.apk" /> </sequential> </for>