Aspectos fundamentales de la app

Las apps para Android se pueden escribir con Kotlin, los lenguajes de programación Java y C++. La compilación de las herramientas del SDK de Android el código, junto con los archivos de datos y recursos, en un APK o Android App Bundle.

Un paquete de Android, que es un archivo de almacenamiento con el sufijo .apk, contiene el contenido de una app para Android requerido en el tiempo de ejecución, y es el archivo que usan para instalar la app.

Un Android App Bundle, que es un archivo de almacenamiento con el sufijo .aab, contiene el contenido de un proyecto de aplicación de Android, incluidos algunos metadatos adicionales que no se requieren en tiempo de ejecución. Un AAB es un formato de publicación y no se puede instalar en dispositivos Android. Integra se aplaza la generación y firma de APK a una etapa posterior.

Cuando distribuyas tu app a través de Google Play, por ejemplo, los servidores de Google Play generan APKs optimizados que solo contienen los recursos y código que requiere el dispositivo en particular que solicita la instalación de la aplicación.

Cada app para Android se aloja en su propia zona de pruebas de seguridad, protegida por las siguientes funciones de seguridad de Android:

  • El sistema operativo Android es un sistema Linux multiusuario en el que cada aplicación es una usuario diferente.
  • De forma predeterminada, el sistema le asigna a cada aplicación un ID de usuario de Linux único, que solo usan las el sistema y la app es desconocida. El sistema establece permisos para todos los archivos de un app para que solo el ID de usuario asignado a esa app pueda acceder a ellos.
  • Cada proceso tiene su propia máquina virtual (VM), por lo que el código de una app se ejecuta de forma aislada del otras apps.
  • De forma predeterminada, cada aplicación ejecuta su propio proceso de Linux. El sistema Android se inicia el proceso cuando cualquier de los componentes de la app deben ejecutarse y, luego, se cierra el proceso cuando ya no es cuando se necesite o cuando el sistema deba recuperar memoria para otras apps.

El sistema Android implementa el principio de privilegio mínimo. Es decir, cada aplicación, de forma predeterminada, tiene acceso solo a los componentes que necesita para hacer su trabajo y no más. Esto crea un entorno muy seguro en el que una aplicación no puede acceder a partes de el sistema para el que no tiene permiso.

Sin embargo, hay formas de compartir contenido datos con otras apps y para una para acceder a los servicios del sistema:

  • Es posible disponer que dos apps compartan el mismo ID de usuario de Linux, en cuyo caso. entre ellas pueden acceder a los archivos de los demás. Para conservar los recursos del sistema, las apps con el con el mismo ID de usuario también puede organizar la ejecución en el mismo proceso de Linux y compartir la misma VM. El las apps también deben estar firmadas con el mismo certificado.
  • Una app puede solicitar permiso para acceder a los datos del dispositivo, como ubicación, cámara y conexión Bluetooth. El usuario tiene para otorgar de forma explícita estos permisos. Para obtener más información sobre los permisos, consulta Permisos en Android.

En el resto de este documento, se describen los siguientes conceptos:

  • Los componentes del marco de trabajo central que definen tu aplicación.
  • El archivo de manifiesto en el que declaras los componentes y el dispositivo requerido para tus .
  • Recursos independientes del código de la app y que permiten que la app optimizar correctamente su comportamiento para una variedad de configuraciones de dispositivos.

Componentes de la aplicación

Los componentes de la app son los componentes fundamentales de una app para Android. Cada es un punto de entrada a través del cual el sistema o un usuario pueden ingresar a tu aplicación. Algunos los componentes dependen de otros.

Hay cuatro tipos de componentes de una aplicación:

  • Actividades
  • Servicios
  • Receptores de emisiones
  • Proveedores de contenido

Cada tipo cumple un propósito específico y tiene un ciclo de vida diferente que define cómo se crea y se destruye un componente. En las siguientes secciones, se detallan los cuatro tipos de componentes de la aplicación.

Actividades
Una actividad es el punto de entrada para interactuar con el usuario. Representa un único pantalla con una interfaz de usuario. Por ejemplo: una app de correo electrónico puede tener una actividad que muestra una lista de los nuevos correos electrónicos, otra actividad para redactar un correo electrónico y otra actividad para leer correos electrónicos. Si bien las actividades trabajan en conjunto para formar una experiencia de usuario cohesiva en la aplicación de correo electrónico; cada una es independiente de los demás.

Una app diferente puede iniciar cualquiera de estas si la aplicación de correo lo permite. Por ejemplo, una app de cámara puede iniciar actividad en la app de correo electrónico para redactar un nuevo mensaje y permitirle al usuario compartir una imagen.

Una actividad posibilita las siguientes interacciones clave entre el sistema y la aplicación:

  • Realizar un seguimiento de lo que le importa actualmente al usuario (lo que aparece en pantalla) para que la sigue ejecutando el proceso que aloja la actividad.
  • Saber qué procesos usados anteriormente contienen actividades detenidas a las que el usuario puede volver y priorizar esos procesos en mayor medida para que estén disponibles.
  • Ayudar a la app a controlar la finalización de su proceso para que el usuario pueda volver a las actividades y restablecido su estado anterior.
  • Permitir que las aplicaciones implementen flujos de usuarios entre sí y que el sistema coordinar estos flujos. El principal ejemplo de esto es el uso compartido.

Se implementa una actividad como una subclase de la clase Activity. Para ver más información sobre la clase Activity, consulta Introducción a las actividades.

Servicios
Un servicio es un punto de entrada de uso general para mantener una app ejecutándose en segundo plano. por toda clase de razones. Es un componente que se ejecuta en segundo plano para realizar operaciones de larga duración las operaciones o el trabajo para procesos remotos. Un servicio no proporciona una interfaz de usuario.

Para Por ejemplo, un servicio podría reproducir música en segundo plano mientras el usuario se encuentra en otra app. podría recuperar datos en la red sin bloquear la interacción del usuario con una actividad. Otro por lotes, como una actividad, puede iniciar el servicio y permitir que se ejecute o vincularse a él para interactúan con él.

Hay dos tipos de servicios que le indican al sistema cómo administrar una app: servicios iniciados y servicios vinculados.

Los servicios iniciados le indican al sistema que los siga ejecutando hasta que se complete su trabajo. Por ejemplo, para sincronizar algunos datos en segundo plano o reproducir música incluso después de que el usuario sale de la app. La sincronización de datos en segundo plano o la reproducción de música representan diferentes tipos de instancias que el sistema maneja de manera diferente:

  • La reproducción de música es algo de lo que el usuario está directamente consciente y la aplicación se lo comunica a el sistema indicando que quiere estar en primer plano, con una notificación que indique al usuario que se está ejecutando. En este caso, el sistema prioriza mantener la configuración porque el usuario tiene una mala experiencia si desaparece.
  • Un servicio normal en segundo plano no es algo de lo que el usuario sea consciente, así que el sistema tiene más libertad para administrar su proceso. Puede dejar que lo maten, reiniciar el servicio en algún momento, si necesita RAM para cosas que son al usuario de inmediato.

Los servicios vinculados se ejecutan porque otra app (o el sistema) indicó que quiere usar el servicio. Un servicio enlazado proporciona una API a otro proceso, y el sistema sabe que hay una dependencia entre estos procesos. Entonces, si el proceso A está vinculado a un servicio en proceso B, el sistema sabe que debe mantener el proceso B y su servicio ejecutándose para A. Además, si el proceso A es algo que le importa al usuario y, luego, sabe que debe tratar al proceso B como algo al usuario también.

Debido a su flexibilidad, los servicios son útiles y los componentes básicos para todo tipo de conceptos de sistemas de nivel superior. Fondos de pantalla animados y notificaciones objetos de escucha, protectores de pantalla, métodos de entrada, servicios de accesibilidad y muchas otras funciones principales del sistema se compilan como servicios a los que implementan las aplicaciones y a los que se vincula el sistema cuando se ejecutan.

Se implementa un servicio como una subclase de Service. Más información sobre la clase Service; consulta la Descripción general de los servicios.

Nota: Si tu app se orienta a Android 5.0 (nivel de API 21) o versiones posteriores, haz lo siguiente: usa la clase JobScheduler para programar acciones. JobScheduler tiene ventaja de ahorrar batería al programar de forma óptima las tareas para reducir el consumo de energía y trabajar con la API de Descanso. Para obtener más información sobre el uso de esta clase, consulta el archivo JobScheduler. documentación de referencia.

Receptores de emisiones
Un receptor de emisión es un componente que permite que el sistema entregue eventos al fuera de un flujo de usuarios normal para que la app pueda responder a la transmisión en todo el sistema anuncios. Como los receptores de emisión son otra entrada bien definida a la app, el sistema puede enviar transmisiones incluso a apps que actualmente no están en ejecución.

Por ejemplo, una app puede programar una alarma para publicar una notificación y avisarle al usuario sobre un evento próximo Como la alarma se envía a un BroadcastReceiver en la app, no es necesario que esta seguirán funcionando hasta que suene la alarma.

Muchas transmisiones se originan en el sistema, como una que anuncia que la pantalla está apagada. la batería está baja o se toma una fotografía. Las aplicaciones también pueden iniciar transmisiones, como para permitir que otras aplicaciones sepan que se descargan algunos datos en el dispositivo y están disponibles para su uso.

Si bien la transmisión Los receptores no muestran una interfaz de usuario, pueden crear una notificación en la barra de estado. para alertar al usuario cuando ocurre un evento de transmisión. Sin embargo, es más habitual que un receptor de emisión solo una puerta de enlace a otros componentes y está destinada a hacer una cantidad mínima de trabajo.

Por ejemplo, un receptor de emisión podría programar un JobService para realizar un trabajo basado en un evento con JobScheduler Los receptores de emisión suelen implicar apps que interactúan entre sí, por lo que es importante implicancias de seguridad cuando se configuran.

Un receptor de emisión se implementa como una subclase de BroadcastReceiver, Cada transmisión se entrega como un objeto Intent. Para obtener más información, consulta la clase BroadcastReceiver.

Proveedores de contenido
Un proveedor de contenido administra un conjunto compartido de datos de la app que puedes almacenar en el sistema de archivos, en una base de datos SQLite, en la Web o en cualquier otro almacenamiento persistente ubicación a la que tu a los que la app puede acceder. A través del proveedor de contenido, otras apps pueden realizar consultas o modificaciones los datos, si el proveedor de contenido lo permite.

Por ejemplo, el sistema Android proporciona una red de contenido proveedor de servicios de nube que administra la información de contacto del usuario. Cualquier app con la permisos pueden consultar al proveedor de contenido, como usar ContactsContract.Data, para leer y escribir información sobre una persona en particular.

Resulta tentador pensar en un proveedor de contenido como una abstracción en una base de datos, porque hay una mucha API y compatibilidad integrada para ese caso común. Sin embargo, tienen un enfoque diferente desde una perspectiva del diseño del sistema.

Para el sistema, un proveedor de contenido es un punto de entrada a una app para publicar elementos de datos con nombre. identificados por un esquema de URI. Así, una aplicación puede decidir cómo desea asignar los datos que contiene a una Espacio de nombres de URI entregando esos URI a otras entidades que, a su vez, pueden usarlos para acceder al de datos no estructurados. Esto permite que el sistema realice algunas acciones en particular para administrar una app:

  • Asignar un URI no requiere que la aplicación permanezca ejecutándose, por lo que los URI pueden persistir después de su de las apps propietarias. El sistema solo necesita asegurarse de que la app propietaria esté que siguen en ejecución cuando recupera los datos de la app desde el URI correspondiente.
  • Estos URI también ofrecen un modelo de seguridad importante y detallado. Por ejemplo, un la app puede colocar el URI de una imagen que tiene en el portapapeles, pero dejar su contenido bloqueado para que otras aplicaciones no puedan acceder libremente a él. Cuando una segunda app intenta para acceder a ese URI en el portapapeles, el sistema puede permitir acceder a los datos mediante un otorgamiento de permiso de URI temporal para que acceda a los datos solo detrás de ese URI y nada más en la segunda app.

Los proveedores de contenido también son útiles para leer y escribir datos privados de tu app y no se comparten.

Se implementa un proveedor de contenido como una subclase de ContentProvider. además de implementar un conjunto estándar de APIs que permitan que otras apps realicen transacciones de contenedores. Para obtener más información, consulta con el desarrollador de Proveedores de contenido. .

Un aspecto exclusivo del diseño del sistema Android es que cualquier aplicación puede iniciar otra componente de una aplicación. Por ejemplo, si quieres que el usuario capture un foto con la cámara del dispositivo, probablemente haya otra app que lo haga, y tu en lugar de desarrollar una actividad para tomar una foto. No deberá incorporar o incluso vincular al código de la aplicación de la cámara. En su lugar, puedes iniciar la actividad en la app de cámara que captura una foto. Cuando termines, la foto aparecerá en tu aplicación para que puedas usarla. Para el usuario, para que parezca que la cámara en realidad forma parte de tu app.

Cuando el sistema inicia un componente, inicia el proceso para esa app. De lo contrario, ya se está ejecutando y crea una instancia de las clases necesarias para el componente. Por ejemplo, si tu inicia la actividad en la aplicación de cámara que toma una foto, esa actividad se ejecuta en el proceso que pertenece a la app de cámara, no en el proceso de tu app. Por lo tanto, a diferencia de las apps de la mayoría de los demás sistemas, las apps de Android no tienen una sola entrada punto: no hay ninguna función main().

Debido a que el sistema ejecuta cada aplicación en un proceso independiente con permisos de archivo que restringir el acceso a otras aplicaciones, la aplicación no puede activar directamente un componente desde otra app. Sin embargo, el sistema Android sí puede hacerlo. Para activar un componente en otra app, entregas un mensaje al sistema que especifica tu intent a iniciar un componente en particular. Luego, el sistema activa ese componente por ti.

Activa componentes

Un mensaje asíncrono, llamado intent, activa tres de los cuatro tipos de componentes: actividades, servicios y de transmisiones continuas. Las intents vinculan componentes entre sí durante el tiempo de ejecución. Puedes pensar en ellas como los mensajeros que solicitan una acción de otros componentes, ya sea que el componente pertenezca a tu app u otra.

Se crea un intent con un objeto Intent, que define un mensaje para activar un componente específico (un intent explícito) o un tipo específico de componente (un intent implícito).

Para las actividades y los servicios, un intent define la acción que se debe realizar, como ver o envía algo y podrías especificar el URI de los datos sobre los que se debe actuar, entre otros elementos que el componente que se está iniciando debe conocer.

Por ejemplo, un intent podría transmitir una solicitud de un para mostrar una imagen o abrir una página web. En algunos casos, puedes iniciar una para recibir un resultado, en cuyo caso la actividad también muestra el resultado en una Intent. También puedes emitir un intent para permitir el usuario debe elegir un contacto personal y hacer que se lo devuelva. El intent que se muestra incluye un URI que apunta al contacto elegido.

Para los receptores de emisión, el intent define la de anuncios. Por ejemplo, un anuncio que indique que la batería del dispositivo está baja incluye solo una cadena de acción conocida que indica que la batería está baja.

A diferencia de las actividades, los servicios y los receptores de emisión, se activa cuando se orienta a una solicitud de ContentResolver. El contenido el agente de resolución maneja todas las transacciones directas con el proveedor de contenido y el componente cuando realiza transacciones con los métodos de llamada al proveedor en la ContentResolver. Esto deja una capa de abstracción por motivos de seguridad entre los el proveedor de contenido y el componente que solicita información.

Existen métodos independientes para activar cada tipo de componente:

  • Puedes iniciar una actividad o darle algo nuevo que hacer. pasando un Intent a startActivity() o, cuando quieres que la actividad devuelva un resultado, startActivityForResult()
  • En Android 5.0 (nivel de API 21) y versiones posteriores, puedes usar la clase JobScheduler para programar acciones. Para versiones anteriores de Android, puedes comenzar un servicio o le dan instrucciones nuevas a un servicio continuo pasando un Intent a startService(). Puedes establecer una vinculación con el servicio pasando un Intent a bindService()
  • Para iniciar una transmisión, pasa un Intent a métodos como sendBroadcast() o sendOrderedBroadcast()
  • Puedes realizar una consulta a un proveedor de contenido llamando query() en un ContentResolver.

Para obtener más información sobre el uso de intents, consulta la documentación de Intents y Filtros de intents. En los siguientes documentos, encontrarás más información para activar componentes específicos: Introducción a las actividades, Descripción general de los servicios, BroadcastReceiver y Proveedores de contenido.

El archivo de manifiesto

Antes de que el sistema Android pueda iniciar un componente de la aplicación, el sistema debe saber que el Para ello, lee el archivo de manifiesto de la app, AndroidManifest.xml. Tu app declara todos sus componentes en este archivo, que se encuentra en la raíz de la directorio del proyecto de la app.

El manifiesto puede hacer ciertas cosas además de declarar los componentes de la aplicación, como los siguientes:

  • Identifica los permisos del usuario que requiere la aplicación, como acceso a Internet o acceso de lectura a los contactos del usuario.
  • Declara el mínimo Nivel de API que requiere la app según las APIs que usa.
  • Declara las funciones de hardware y software que la app usa o requiere, como una cámara. servicios Bluetooth o una pantalla multitáctil.
  • Declara las bibliotecas de APIs con las que la app debe estar vinculada (aparte del framework de Android). APIs), como Biblioteca de Google Maps

Cómo declarar componentes

La tarea principal del manifiesto es informar al sistema sobre los componentes de la aplicación. Para Por ejemplo, un archivo de manifiesto puede declarar una actividad de la siguiente manera:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:icon="@drawable/app_icon.png" ... >
        <activity android:name="com.example.project.ExampleActivity"
                  android:label="@string/example_label" ... >
        </activity>
        ...
    </application>
</manifest>

En <application> , el atributo android:icon apunta a los recursos de un ícono que identifica la .

En el elemento <activity>, El atributo android:name especifica el nombre de clase completamente calificado del la subclase Activity y el El atributo android:label especifica una cadena. usar como etiqueta visible para el usuario de la actividad.

Debes declarar todos los componentes de la aplicación mediante estos elementos:

Actividades, servicios y proveedores de contenido que incluyes en tu fuente, pero que no declaras del manifiesto no son visibles para el sistema y, en consecuencia, no se pueden ejecutar. Sin embargo, transmitir Los receptores se pueden declarar en el manifiesto o crearse dinámicamente en el código, como BroadcastReceiver objetos y registrados en el sistema llamando registerReceiver()

Para obtener más información sobre cómo estructurar el archivo de manifiesto de tu app, consulta la Descripción general del manifiesto de la app.

Declara las capacidades de los componentes

Como se explicó en la sección Activar componentes, puedes usar un Intent para iniciar actividades, servicios y receptores de emisión Tú lo haces Nombrando explícitamente el componente de destino, con el nombre de clase del componente, en el intent. También puedes usar un intent implícito, que describe el tipo de acción que se debe realizar y, opcionalmente, los datos que deseas realizar la acción. Un intent implícito permite que el sistema encuentre un componente en el dispositivo. que pueda realizar los acción e iniciarla. Si hay varios componentes que pueden realizar la acción que se describe en el el usuario selecciona cuál usar.

Precaución: Si usas un intent para iniciar un Service, asegúrate de que tu app sea segura con una explícito . El uso de un intent implícito para iniciar un servicio es una de seguridad porque no puedes estar seguro de qué servicio responde a la intent y el usuario no puede ver qué servicio se inicia. A partir de Android 5.0 (nivel de API 21), el sistema arroja una excepción si llamas a bindService() con un intent implícito. No declares filtros de intents para tus servicios.

El sistema identifica los componentes que pueden responder a una intent comparando los intent recibido a los filtros de intents proporcionados en el archivo de manifiesto de otras aplicaciones en el dispositivo.

Cuando declaras una actividad en el manifiesto de tu app, tienes la opción de incluir filtros de intents que declaran las capacidades de la actividad para que pueda responder a intents de otras apps. Para hacer esto, Agrega un elemento <intent-filter> como elemento secundario del elemento de declaración del componente.

Por ejemplo, si creas una aplicación de correo electrónico con una actividad para redactar un nuevo correo electrónico, puedes declarar un filtro de intents para responder a "enviar" para enviar un correo electrónico nuevo, como se muestra en el siguiente ejemplo:

<manifest ... >
    ...
    <application ... >
        <activity android:name="com.example.project.ComposeEmailActivity">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <data android:type="*/*" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Si otra app crea un intent con la acción ACTION_SEND y se lo pasa a startActivity(), el sistema puede iniciar tu actividad para que el usuario pueda redactar y enviar una correo electrónico.

Para obtener más información sobre cómo crear filtros de intents, consulta el documento Intents y filtros de intents.

Declara los requisitos de la app

Existen varios dispositivos con la tecnología de Android, y no todos ofrecen la con las mismas funciones y capacidades. Para evitar que tu app se instale en dispositivos que carecen de las funciones que tu app necesita, es importante que definas claramente un perfil para los tipos de dispositivos compatibles con tu app declarando los requisitos de dispositivo y software en la .

La mayoría de estas declaraciones son solo informativas. El sistema no lee pero los servicios externos, como Google Play, sí los leen para proporcionar filtros. para los usuarios cuando busquen apps desde sus dispositivos.

Por ejemplo, supongamos que tu app requiere una cámara y usa APIs introducidas en Android 8.0 (nivel de API 26). Debe declarar estos requisitos. Los valores para minSdkVersion y targetSdkVersion se establecen en el archivo build.gradle del módulo de tu app:

android {
  ...
  defaultConfig {
    ...
    minSdkVersion 26
    targetSdkVersion 29
  }
}

Nota: No configures minSdkVersion ni targetSdkVersion directamente en el archivo de manifiesto, ya que Gradle las reemplaza durante el proceso de compilación. Para obtener más información, consulta Especifica los requisitos de nivel de API.

Debes declarar la función de cámara en el archivo de manifiesto de tu app:

<manifest ... >
    <uses-feature android:name="android.hardware.camera.any"
                  android:required="true" />
    ...
</manifest>

Con las declaraciones de estos ejemplos, los dispositivos que no tienen un cámara La versión de Android anterior a 8.0 no puede instalar tu app desde Google Play. Sin embargo, también puedes declarar que tu app usa la cámara, pero no Solicitar. Para ello, configura el objeto required a false, comprueba durante el tiempo de ejecución si que el dispositivo tenga cámara e inhabilitar las funciones de cámara según sea necesario.

Más información para administrar la compatibilidad de tu app con diferentes dispositivos se proporciona en la Descripción general de compatibilidad de dispositivos.

Recursos de la app

Una app para Android se compone de mucho más que solo código. Requiere recursos que sean independiente del código fuente, como imágenes, archivos de audio y cualquier elemento relacionado con la presentación de la aplicación. Por ejemplo, puedes definir animaciones, menús, estilos, colores y el diseño de las interfaces de usuario de la actividad con archivos en formato XML.

Usar los recursos de la aplicación para actualizar varias características de tu app sin modificar el código. Proporcionando conjuntos de recursos alternativos te permite optimizar tu app para una variedad de configuraciones de dispositivos, como diferentes idiomas y tamaños de pantalla.

Por cada recurso que incluyes en tu proyecto de Android, las herramientas de compilación del SDK definen un de entero, que puedes usar para hacer referencia al recurso desde el código de tu aplicación o desde otros recursos definidos en XML. Por ejemplo, si tu app contiene un archivo de imagen llamado logo.png (guardado en el directorio res/drawable/), las herramientas del SDK generan un ID de recurso llamado R.drawable.logo. Este ID se asigna a un número entero específico de la aplicación, que que puedes usar para hacer referencia a la imagen e insertarla en tu interfaz de usuario.

Uno de los aspectos más importantes de proporcionar recursos separados del código fuente es la capacidad de proporcionar recursos alternativos para diferentes parámetros de configuración.

Por ejemplo, al definir cadenas de IU en XML, puedes traducir las cadenas en otras y guarda esas cadenas en archivos separados. Luego, Android aplica el cadenas de lenguaje apropiadas a la IU en función de un calificador de idioma que agregas al nombre del directorio de recursos, como res/values-fr/ para la cadena en francés. y la configuración de idioma del usuario.

Android admite muchos calificadores para tus recursos alternativos. El calificador es una cadena corta que incluyes en el nombre de tus directorios de recursos para definen la configuración del dispositivo para la que se usan esos recursos.

Para ejemplo, puedes crear diferentes diseños para tus actividades en función del la orientación y el tamaño de la pantalla del dispositivo. Cuando la pantalla del dispositivo está en posición vertical (alta) orientación, tal vez quieras un diseño con botones organizados verticalmente, pero cuando la pantalla esté con orientación horizontal (amplia), es posible que quieras que los botones estén alineados horizontalmente. Cómo cambiar el diseño según la orientación, puedes definir dos diseños y aplicar las calificador para el nombre de directorio de cada diseño. Luego, el sistema aplica automáticamente las políticas en función de la orientación actual del dispositivo.

Para obtener más información sobre los distintos tipos de recursos que puedes incluir en tu aplicación y cómo crear recursos alternativos para diferentes configuraciones de dispositivos, lee la Descripción general de recursos de la app. Para obtener más información sobre las prácticas recomendadas y el diseño de apps sólidas y de calidad de producción, consulta la Guía de arquitectura de apps.

Recursos adicionales

Para aprender sobre el desarrollo de Android con videos y tutoriales de código, consulta la Cómo desarrollar apps para Android con Kotlin de Udacity.

Continúa leyendo:

Intents y filtros de intents
Aprende a usar las APIs de Intent para activar componentes de la app, como actividades y servicios, y cómo hacer que los componentes de tu app disponibles para que las usen otras apps.
Introducción a las actividades
Aprende a crear una instancia de la clase Activity. que proporciona una pantalla distintiva en tu aplicación con una interfaz de usuario.
Descripción general de los recursos de la app
Descubre cómo se estructuran las apps para Android en recursos independientes de la app de la código de la app, incluido el modo en que puedes proporcionar recursos alternativos para dispositivos específicos parámetros de configuración.

También de interés:

Descripción general de la compatibilidad de dispositivos
Descubre cómo funciona Android en diferentes tipos de dispositivos y cómo puedes optimizar tu app para cada dispositivo o restringir su disponibilidad a diferentes dispositivos.
Permisos en Android
Obtén información sobre cómo Android restringe el acceso de las apps a ciertas APIs con un permiso que requiere el consentimiento del usuario para que tu app use esas APIs.