The Android Developer Challenge is back! Submit your idea before December 2.

Cómo configurar variantes de compilación

Esta página se basa en las especificaciones de Descripción general de la configuración de tu compilación con el propósito de mostrarte la manera de configurar variantes de compilación para crear diferentes versiones de tu app a partir de un mismo proyecto, y de administrar correctamente tus dependencias y configuraciones de firma.

Cada variante de compilación representa una versión diferente de tu app que puedes compilar. Por ejemplo, es posible que desees compilar una versión de tu app que sea gratuita, con contenido limitado, y una versión paga que incluya más contenido. También puedes compilar diferentes versiones de tu app para diferentes dispositivos, según el nivel de API y otras variantes de dispositivos. No obstante, si deseas compilar diferentes versiones según la ABI del dispositivo o la densidad de pantalla, puedes compilar varios APK.

Las variantes de compilación surgen del uso de un conjunto específico de reglas a través de Gradle para combinar configuraciones, código y recursos configurados en tus tipos de compilación y tipos de productos. Aunque no configuras variantes de compilación directamente, sí configuras los tipos de compilación y los tipos de productos que las forman.

Por ejemplo, en un tipo de producto de "demostración" pueden especificarse diferentes características y requisitos de dispositivo, como código fuente personalizado, y recursos y niveles de API mínimos, mientras que en el tipo de compilación de "depuración" se aplican diferentes configuraciones de compilación y empaquetado, como opciones de depuración y claves de firma. La variante de compilación resultante es la versión "demoDebug" de tu app, que incluye una combinación de las configuraciones y los recursos incluidos en el tipo de producto "demostración", el tipo de compilación "depuración" y el conjunto de orígenes main/.

Cómo configurar tipos de compilaciones

Puedes crear y configurar tipos de compilaciones en el archivo build.gradle de nivel de módulo dentro del bloque android. Cuando creas un módulo nuevo, Android Studio crea automáticamente los tipos de compilación de depuración y lanzamiento. Si bien el tipo de compilación de depuración no aparece en el archivo de configuración de la compilación, Android Studio lo configura con debuggable true. Esta configuración te permite depurar la app en dispositivos Android seguros y configura la firma del APK con un almacén de claves de depuración genérico.

Puedes agregar el tipo de compilación de depuración a tu configuración si deseas agregar o cambiar determinadas opciones de configuración. En el siguiente ejemplo, se especifica un applicationIdSuffix para el tipo de compilación de depuración, y se configura un tipo de compilación "de prueba" que se inicializa con la configuración del tipo de compilación de depuración.

    android {
        defaultConfig {
            manifestPlaceholders = [hostName:"www.example.com"]
            ...
        }
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }

            debug {
                applicationIdSuffix ".debug"
                debuggable true
            }

            /**
             * The `initWith` property allows you to copy configurations from other build types,
             * then configure only the settings you want to change. This one copies the debug build
             * type, and then changes the manifest placeholder and application ID.
             */
            staging {
                initWith debug
                manifestPlaceholders = [hostName:"internal.example.com"]
                applicationIdSuffix ".debugStaging"
            }
        }
    }
    

Nota: Cuando realizas cambios en un archivo de configuración de la compilación, Android Studio exige que sincronices tu proyecto con la nueva configuración. Para sincronizar tu proyecto, puedes hacer clic en Sincronizar ahora en la barra de notificaciones que aparece cuando realizas un cambio, o bien en Sincronizar proyecto en la barra de herramientas. Si Android Studio detecta un error en la configuración, aparecerá la ventana Mensajes y se describirá el problema.

Para obtener más información sobre todas las propiedades que puedes configurar con tipos de compilación, lee la referencia DSL del tipo de compilación.

Cómo configurar tipos de productos

Crear tipos de productos es similar a crear tipos de compilación: agrégalos al bloque productFlavors de tu configuración e incluye los ajustes que desees. Los tipos de productos admiten las mismas propiedades que defaultConfig, ya que defaultConfig en realidad pertenece a la clase ProductFlavor. Por lo tanto, puedes proporcionar la configuración básica para todos los tipos en el bloque defaultConfig, y cada tipo puede anular cualquiera de estos valores predeterminados, como applicationId. Para obtener más información sobre el ID de aplicación, consulta Cómo configurar el ID de aplicación.

Nota: Debes especificar un nombre de paquete con el atributo package en el archivo de manifiesto main/. También debes usar ese nombre de paquete en tu código fuente para hacer referencia a la clase R, o bien resolver cualquier actividad o registro de servicio relacionados, lo que te permite usar applicationId a fin de asignar a cada tipo de producto un ID único para el empaquetado y la distribución sin necesidad de cambiar tu código fuente.

Todos los tipos deben pertenecer a una dimensión denominada, que es un grupo de tipos de productos. Debes asignar todos los tipos a una dimensión; de lo contrario, obtendrás el siguiente error de compilación. Si un módulo dado especifica solo una dimensión de tipo, el complemento de Android para Gradle asignará automáticamente todos los tipos del módulo a esa dimensión.

      Error:All flavors must now belong to a named flavor dimension.
      The flavor 'flavor_name' is not assigned to a flavor dimension.
    

En el siguiente código de ejemplo, se crea una dimensión de tipo denominada "versión" y se agregan los tipos de producto "demo" y "completo". Estos tipos proporcionan sus propios applicationIdSuffix y versionNameSuffix:

    android {
        ...
        defaultConfig {...}
        buildTypes {
            debug{...}
            release{...}
        }
        // Specifies one flavor dimension.
        flavorDimensions "version"
        productFlavors {
            demo {
                // Assigns this product flavor to the "version" flavor dimension.
                // If you are using only one dimension, this property is optional,
                // and the plugin automatically assigns all the module's flavors to
                // that dimension.
                dimension "version"
                applicationIdSuffix ".demo"
                versionNameSuffix "-demo"
            }
            full {
                dimension "version"
                applicationIdSuffix ".full"
                versionNameSuffix "-full"
            }
        }
    }
    

Nota: Para distribuir tu app usando Compatibilidad con varios APK en Google Play, asigna el mismo valor de applicationId a todas las variantes, pero un versionCode diferente a cada una. Para distribuir diferentes variantes de tu app como apps independientes en Google Play, debes asignar un applicationId diferente a cada variante.

Después de crear y configurar tus tipos de productos, haz clic en Sincronizar ahora en la barra de notificaciones. Al finalizar la sincronización, Gradle crea automáticamente variantes de compilación en función de tus tipos de compilación y tipos de productos, y las denomina conforme a <product-flavor><Build-Type>. Por ejemplo, si creaste tipos de producto "demostración" y "completo", y conservaste los tipos de compilación predeterminados de "depuración" y "lanzamiento", Gradle crea las siguientes variantes de compilación:

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

Puedes cambiar la variante de compilación por la que desees para la compilación y la ejecución. Simplemente, dirígete a Compilación > Seleccionar variante de compilación y selecciona una del menú desplegable. Sin embargo, para comenzar a personalizar cada variante de compilación con sus propias funciones y recursos, deberás saber cómo crear y administrar conjuntos de fuentes.

Cómo combinar varios tipos de productos con dimensiones de tipos

En algunos casos, es posible que desees combinar configuraciones de varios tipos de productos. Por ejemplo, puedes crear diferentes configuraciones para los tipos de productos "completo" y "demostración" que se basen en el nivel de API. Para hacerlo, el complemento de Android para Gradle te permite crear varios grupos de productos como dimensiones de tipos. Cuando compilas tu app, Gradle combina una configuración de tipo de producto de cada dimensión de tipo que defines, junto con una configuración de tipo de compilación, para crear la variante de compilación final. Gradle no combina tipos de productos que pertenecen a la misma dimensión de tipo.

Sugerencia: Para crear versiones diferentes de tu app según la densidad de pantalla y la ABI, debes compilar varios APK, en lugar de usar tipos de productos.

En el siguiente código de ejemplo, se usa la propiedad flavorDimensions para crear una dimensión de tipo "modo" a fin de agrupar los tipos de productos "completo" y "demo", y una dimensión de tipo "api" a fin de agrupar las configuraciones de tipos de productos basadas en el nivel de API:

    android {
      ...
      buildTypes {
        debug {...}
        release {...}
      }

      // Specifies the flavor dimensions you want to use. The order in which you
      // list each dimension determines its priority, from highest to lowest,
      // when Gradle merges variant sources and configurations. You must assign
      // each product flavor you configure to one of the flavor dimensions.
      flavorDimensions "api", "mode"

      productFlavors {
        demo {
          // Assigns this product flavor to the "mode" flavor dimension.
          dimension "mode"
          ...
        }

        full {
          dimension "mode"
          ...
        }

        // Configurations in the "api" product flavors override those in "mode"
        // flavors and the defaultConfig block. Gradle determines the priority
        // between flavor dimensions based on the order in which they appear next
        // to the flavorDimensions property above--the first dimension has a higher
        // priority than the second, and so on.
        minApi24 {
          dimension "api"
          minSdkVersion 24
          // To ensure the target device receives the version of the app with
          // the highest compatible API level, assign version codes in increasing
          // value with API level. To learn more about assigning version codes to
          // support app updates and uploading to Google Play, read Multiple APK Support
          versionCode 30000 + android.defaultConfig.versionCode
          versionNameSuffix "-minApi24"
          ...
        }

        minApi23 {
          dimension "api"
          minSdkVersion 23
          versionCode 20000  + android.defaultConfig.versionCode
          versionNameSuffix "-minApi23"
          ...
        }

        minApi21 {
          dimension "api"
          minSdkVersion 21
          versionCode 10000  + android.defaultConfig.versionCode
          versionNameSuffix "-minApi21"
          ...
        }
      }
    }
    ...
    

La cantidad de variantes de compilación que crea Gradle es igual al producto de la cantidad de tipos de cada dimensión de tipo y la cantidad de tipos de compilación que configuras. Cuando Gradle asigna un nombre a cada variante de compilación o APK correspondiente, los tipos de productos pertenecientes a la dimensión de tipo de mayor prioridad aparecen primero; luego, aparecen aquellos de dimensiones de menor prioridad y, por último, el tipo de compilación. Con la configuración de compilación anterior como ejemplo, Gradle crea un total de 12 variantes de compilación con el siguiente esquema de nomenclatura:

Variante de compilación: [minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
APK correspondiente: app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
Por ejemplo:
Variante de compilación: minApi24DemoDebug
APK correspondiente: app-minApi24-demo-debug.apk

Además de los directorios de conjuntos de fuentes que puedes crear para cada tipo de producto y variante de compilación en particular, también puedes crear directorios de conjuntos de orígenes para cada combinación de tipos de productos. Por ejemplo, puedes crear y agregar fuentes Java al directorio src/demoMinApi24/java/, y Gradle las usará únicamente cuando compile una variante que combine esos dos tipos de productos. Los conjuntos de fuentes que creas para las combinaciones de tipos de productos tienen una prioridad superior con respecto a aquellos que pertenecen a cada tipo de producto en particular. Para obtener más información sobre los conjuntos de fuentes y la manera en que Gradle fusiona recursos, consulta la sección Cómo crear conjuntos de fuentes.

Cómo filtrar variantes

Gradle crea una variante de compilación para cada combinación posible de los tipos de productos y de compilación que configuras. Sin embargo, es posible que determinadas variantes de compilación no sean necesarias o no tengan sentido en el contexto de tu proyecto. Puedes quitar determinadas configuraciones de variantes de compilación mediante un filtro en el archivo build.gradle del nivel del módulo.

Con la configuración de compilación de la sección anterior como ejemplo, supongamos que planeas admitir solo los niveles de API 23 y versiones posteriores para la versión demostración de la app. Puedes usar el bloque variantFilter para filtrar todas las configuraciones de variantes de compilación en las que se combinen los tipos de productos "minApi21" y "demo":

    android {
      ...
      buildTypes {...}

      flavorDimensions "api", "mode"
      productFlavors {
        demo {...}
        full {...}
        minApi24 {...}
        minApi23 {...}
        minApi21 {...}
      }

      variantFilter { variant ->
          def names = variant.flavors*.name
          // To check for a certain build type, use variant.buildType.name == "<buildType>"
          if (names.contains("minApi21") && names.contains("demo")) {
              // Gradle ignores any variants that satisfy the conditions above.
              setIgnore(true)
          }
      }
    }
    ...
    

Una vez que agregas un filtro de variantes a tu configuración de compilación y haces clic en Sincronizar ahora en la barra de notificaciones, Gradle omite cualquier variante de compilación que cumpla con las condiciones que especifiques, y estas dejan de aparecer en el menú desplegable cuando haces clic en Compilación > Seleccionar variante de compilación en la barra de menú (o Variantes de compilación en la barra de la ventana de herramientas).

Cómo crear conjuntos de fuentes

De forma predeterminada, Android Studio crea el conjunto de fuentes main/ y los directorios para todo lo que deseas compartir entre todas las variantes de compilación. Sin embargo, puedes crear nuevos conjuntos de fuentes a fin de controlar exactamente los archivos que compila y empaqueta Gradle para tipos de compilación, tipos de productos (y combinaciones de tipos de productos cuando se usan dimensiones de tipos) y variantes de compilación específicos. Por ejemplo, puedes definir una funcionalidad básica en el conjunto de fuentes main/ y usar conjuntos de orígenes de tipo de producto a fin de cambiar las pautas de marca de tu app para diferentes clientes, o incluir permisos y funcionalidad de registro especiales solo para las variantes de compilación que usen el tipo de compilación de depuración.

Gradle prevé que organizarás los archivos y directorios del conjunto de fuentes de una manera determinada, semejante a la que se aplica en el conjunto de orígenes main/. Por ejemplo, Gradle prevé que los archivos de la clase Java específicos del tipo de compilación de "depuración" se encuentran en el directorio src/debug/java/.

El complemento de Android para Gradle proporciona una tarea de Gradle útil que te muestra la manera de organizar tus archivos para cada tipo de compilación, tipo de producto y variante de compilación. Por ejemplo, en el siguiente caso del resultado de tarea, se describe el punto en el cual Gradle prevé que encontrará ciertos archivos para el tipo de compilación de "depuración":

    ------------------------------------------------------------
    Project :app
    ------------------------------------------------------------

    ...

    debug
    ----
    Compile configuration: compile
    build.gradle name: android.sourceSets.debug
    Java sources: [app/src/debug/java]
    Manifest file: app/src/debug/AndroidManifest.xml
    Android resources: [app/src/debug/res]
    Assets: [app/src/debug/assets]
    AIDL sources: [app/src/debug/aidl]
    RenderScript sources: [app/src/debug/rs]
    JNI sources: [app/src/debug/jni]
    JNI libraries: [app/src/debug/jniLibs]
    Java-style resources: [app/src/debug/resources]
    

Para ver este resultado, haz lo siguiente:

  1. Haz clic en Gradle a la derecha de la ventana de IDE.
  2. Navega hasta MyApplication > Tasks > android y haz doble clic en sourceSets. Después de que Gradle ejecute la tarea, se abrirá la ventana Run para mostrar el resultado.
  3. Si la pantalla no está en modo texto como se muestra arriba, haz clic en Toggle view , en el lado izquierdo de la ventana Run.

Nota: El resultado de la tarea también te muestra cómo organizar conjuntos de fuentes para los archivos que quieres usar con el fin de ejecutar pruebas para tu app, como conjuntos de fuentes de prueba test/ y androidTest/.

Cuando creas una nueva variante de compilación, Android Studio no crea los directorios del conjunto de orígenes, pero te ofrece algunas opciones que te ayudarán. Por ejemplo, a fin de crear solo el directorio java/ para tu tipo de compilación "depuración", haz lo siguiente:

  1. Abre el panel Proyecto y selecciona la vista Proyecto en el menú desplegable de la parte superior del panel.
  2. Navega hasta MyProject/app/src/.
  3. Haz clic con el botón derecho en el directorio src y selecciona NewFolder > Java Folder.
  4. En el menú desplegable junto a Conjunto de fuentes de destino, selecciona depurar.
  5. Haz clic en Finalizar.

Android Studio crea un directorio de conjunto de orígenes para tu tipo de compilación de depuración y, luego, el directorio java/ dentro de él. De manera alternativa, puedes hacer que Android Studio cree los directorios cuando agregues un nuevo archivo a tu proyecto para una variante de compilación específica. Por ejemplo, a fin de crear un archivo XML de valores para tu tipo de compilación de "depuración", haz lo siguiente:

  1. En el mismo panel Proyecto, haz clic con el botón derecho del mouse en el directorio src y selecciona Nuevo > XML > Archivo XML de valores.
  2. Ingresa el nombre del archivo XML o mantén el nombre predeterminado.
  3. En el menú desplegable junto a Conjunto de fuentes de destino, selecciona depurar.
  4. Haz clic en Finalizar.

Como el tipo de compilación de "depuración" se especificó como conjunto de fuentes de destino, Android Studio genera automáticamente los directorios necesarios cuando se crea el archivo XML. La estructura del directorio resultante debería ser como la que se muestra en la figura 2.

Figura 2: Nuevos directorios de conjuntos de orígenes para el tipo de compilación de "depuración"

Con el mismo procedimiento, también puedes crear directorios del conjunto de fuentes para tipos de productos, como src/demo/, y variantes de compilación como src/demoDebug/. Además, puedes crear conjuntos de fuentes de prueba orientados a variantes de compilación específicas, como src/androidTestDemoDebug/. Para obtener más información, consulta Cómo probar conjuntos de fuentes.

Cómo cambiar configuraciones predeterminadas de conjuntos de fuentes

Si tienes fuentes que no están organizadas en la estructura de archivo de conjunto de fuentes predeterminada que prevé Gradle, como se describe antes en la sección Cómo crear conjuntos de fuentes, puedes usar el bloque sourceSets para cambiar la ubicación en la que Gradle espera reunir los archivos de cada componente de un conjunto de fuentes. No es necesario que reubiques los archivos; solo debes proporcionar a Gradle las rutas de acceso, en relación con el archivo build.gradle de nivel de módulo, en las que Gradle debe encontrar los archivos para cada componente del conjunto de fuentes. Para determinar los componentes que puedes configurar y si puedes asignarlos a varios archivos o directorios, consulta la referencia sobre el complemento de Android para Gradle DSL.

En el siguiente código de ejemplo, se asignan fuentes del directorio app/other/ a determinados componentes del conjunto de orígenes main y se cambia el directorio raíz del conjunto de fuentes androidTest.

    android {
      ...
      sourceSets {
        // Encapsulates configurations for the main source set.
        main {
          // Changes the directory for Java sources. The default directory is
          // 'src/main/java'.
          java.srcDirs = ['other/java']

          // If you list multiple directories, Gradle uses all of them to collect
          // sources. Because Gradle gives these directories equal priority, if
          // you define the same resource in more than one directory, you get an
          // error when merging resources. The default directory is 'src/main/res'.
          res.srcDirs = ['other/res1', 'other/res2']

          // Note: You should avoid specifying a directory which is a parent to one
          // or more other directories you specify. For example, avoid the following:
          // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
          // You should specify either only the root 'other/res1' directory, or only the
          // nested 'other/res1/layouts' and 'other/res1/strings' directories.

          // For each source set, you can specify only one Android manifest.
          // By default, Android Studio creates a manifest for your main source
          // set in the src/main/ directory.
          manifest.srcFile 'other/AndroidManifest.xml'
          ...
        }

        // Create additional blocks to configure other source sets.
        androidTest {

          // If all the files for a source set are located under a single root
          // directory, you can specify that directory using the setRoot property.
          // When gathering sources for the source set, Gradle looks only in locations
          // relative to the root directory you specify. For example, after applying the
          // configuration below for the androidTest source set, Gradle looks for Java
          // sources only in the src/tests/java/ directory.
          setRoot 'src/tests'
          ...
        }
      }
    }
    ...
    

Cómo realizar compilaciones con conjuntos de fuentes

Puedes usar los directorios de conjuntos de fuentes para contener el código y los recursos que deseas empaquetar solo con determinadas configuraciones. Por ejemplo, si compilas la variante de compilación "demoDebug", que es el producto combinado de un tipo de producto de "demostración" y el tipo de compilación de "depuración", Gradle busca en esos directorios y les da la siguiente prioridad:

  1. src/demoDebug/ (conjunto de fuentes de la variante de compilación)
  2. src/debug/ (conjunto de fuentes del tipo de compilación)
  3. src/demo/ (conjunto de fuentes del tipo de producto)
  4. src/main/ (conjunto de fuentes principal)

Nota: Si combinas varios tipos de productos, la prioridad entre ellos se determina por la dimensión de tipo a la que pertenecen. Cuando se muestran las dimensiones de tipos con la propiedad android.flavorDimensions, los tipos de productos que pertenecen a la primera dimensión de tipo que incluyes en la lista tienen mayor prioridad que aquellos que pertenecen a la segunda dimensión de tipo, y así sucesivamente. Además, los conjuntos de fuentes que creas para las combinaciones de tipos de productos tienen una prioridad superior con respecto a los conjuntos de fuentes que pertenecen a cada tipo de producto en particular.

El orden indicado determina el conjunto de orígenes que tiene prioridad más alta cuando Gradle combina código y recursos. Como el directorio del conjunto de orígenes demoDebug/ probablemente contenga archivos específicos para esa variante de compilación, si demoDebug/ incluye un archivo que también definido en debug/, Gradle usa el archivo del conjunto de fuentes demoDebug/. De manera similar, Gradle otorga a los archivos de los conjuntos de fuentes de tipo de compilación y tipo de producto una prioridad más alta con respecto a los mismos archivos en main/. Gradle tiene en cuenta este orden de prioridad al aplicar las siguientes reglas de compilación:

  • Todo el código fuente de los directorios java/ se compila en conjunto para generar un único resultado.

    Nota: Para una variante determinada, Gradle genera un error de compilación si encuentra dos o más directorios de conjuntos de fuentes que hayan definido la misma clase Java. Por ejemplo, al compilar un APK de depuración, no puedes definir src/debug/Utility.java y src/main/Utility.java porque Gradle realiza búsquedas en estos dos directorios durante el proceso de compilación y genera un error de "clase duplicada". Si deseas diferentes versiones de Utility.java para diferentes tipos de compilación, puedes hacer que cada uno de estos defina su propia versión del archivo y no incluirlo en el conjunto de fuentes main/.

  • Los manifiestos se fusionan en un solo manifiesto. La prioridad se da en el mismo orden que la lista anterior. Es decir, la configuración de manifiesto para un tipo de compilación anula la configuración de manifiesto para un tipo de producto, y así sucesivamente. Para obtener más información, lee documentación sobre la fusión de manifiestos.
  • Los archivos en los directorios values/ se fusionan de igual manera. Si dos archivos comparten el mismo nombre, como dos archivos strings.xml, se da prioridad en el mismo orden que el de la lista anterior. Es decir, los valores definidos en un archivo del conjunto de orígenes de tipo de compilación anulan los valores definidos en el mismo archivo de un tipo de producto, y así sucesivamente.
  • Los recursos de los directorios res/ y asset/ se empaquetan juntos. Si hay recursos con el mismo nombre definidos en dos o más conjuntos de orígenes, se da prioridad en el mismo orden que el de la lista anterior.
  • Por último, al compilar el APK, Gradle otorga la prioridad más baja a los recursos y manifiestos incluidos con las dependencias del módulo de biblioteca.

Cómo declarar dependencias

Además, puedes configurar una dependencia para una variante de compilación o un conjunto de fuentes de prueba específicos asignando prefijos al nombre de la variante de compilación o del conjunto de fuentes de prueba antes de la palabra clave de configuración Implementation, como se muestra en el siguiente ejemplo.

    dependencies {
        // Adds the local "mylibrary" module as a dependency to the "free" flavor.
        freeImplementation project(":mylibrary")

        // Adds a remote binary dependency only for local tests.
        testImplementation 'junit:junit:4.12'

        // Adds a remote binary dependency only for the instrumented test APK.
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    }
    

Para obtener más información, consulta Cómo agregar dependencias de compilación.

Cómo configurar ajustes de firma

Gradle no firma el APK de tu compilación de lanzamiento a menos que definas explícitamente una configuración de firma para esa compilación. Puedes crear con facilidad una clave de lanzamiento y firmar tu tipo de compilación de lanzamiento con Android Studio.

Para configurar de forma manual los ajustes de firma de tu tipo de compilación de lanzamiento mediante configuraciones de compilación de Gradle, haz lo siguiente:

  1. Crea un almacén de claves. Un almacén de claves es un archivo ejecutable que contiene un conjunto de claves privadas. Debes conservarlo en un lugar seguro y protegido.
  2. Crea una clave privada. Una clave privada representa la entidad que se identificará con la app, como una persona o una empresa.
  3. Agrega la configuración de firma al archivo build.gradle de nivel de módulo:

        ...
        android {
            ...
            defaultConfig {...}
            signingConfigs {
                release {
                    storeFile file("myreleasekey.keystore")
                    storePassword "password"
                    keyAlias "MyReleaseKey"
                    keyPassword "password"
                }
            }
            buildTypes {
                release {
                    ...
                    signingConfig signingConfigs.release
                }
            }
        }
        

Para generar un APK firmado, selecciona Compilación > Generar APK firmado en la barra de menú. El paquete de app/build/apk/app-release.apk ahora quedará firmado con tu clave de lanzamiento.

Nota: No es una buena práctica de seguridad incluir las contraseñas para tu clave de lanzamiento y almacén de claves dentro del archivo de compilación. Como alternativa, puedes configurar el archivo de compilación para que obtenga estas contraseñas de variables de entorno o que el proceso de compilación te solicite estas contraseñas.

Para obtener estas contraseñas desde variables de entorno, usa el siguiente código:

    storePassword System.getenv("KSTOREPWD")
    keyPassword System.getenv("KEYPWD")
    

Para que el proceso de compilación te solicite estas contraseñas si invocas la compilación desde la línea de comandos, usa el siguiente código:

    storePassword System.console().readLine("\nKeystore password: ")
    keyPassword System.console().readLine("\nKey password: ")
    

Luego de completar este proceso, puedes distribuir tu app y publicarla en Google Play.

Advertencia: Conserva tu keystore y tu clave privada en un lugar seguro y protegido, y asegúrate de contar con copias de seguridad protegidas de ellos. Si publicas una app en Google Play y, luego, pierdes la clave con la que la firmaste, no podrás publicar actualizaciones para ella, ya que siempre deberás firmar todas las versiones con la misma clave.

Cómo firmar apps para Wear OS

Cuando publiques apps para Wear OS, deberás firmar el APK del reloj y opcionalmente el del teléfono. Puedes obtener más información sobre cómo empaquetar y firmar apps para Wear OS en Cómo empaquetar apps para wearables.