Подтвердить что ты не робот

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

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

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

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

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

Спасибо.

4b9b3361

Ответ 1

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

Вы можете решить свою проблему с помощью ant, как это.

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

xml будет выглядеть следующим образом:

ресурС# 1:

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

ресурС# 2:

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

и ant script будет выглядеть следующим образом:

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

Ответ 2

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

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

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

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

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

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

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

Ответ 3

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

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, если приложение подписано с помощью отладочного ключа, и выпуск с сертификатом выпуска.

Ответ 4

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

Ответ 5

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

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

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

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

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

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

И, наконец, я могу запустить ant build-all из командной строки и собрать все четыре цели. Немного больше script, как раз перед концом цели 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}[email protected]{config.name}.apk" />
    </sequential>
</for>