Android — Componentes de la aplicación 03
Las aplicaciones android están hechas de varios componentes. Los componentes principales son:
- Activities
- Fragments
- Intents
- Broadcast receivers
- Content providers and Services
Todos estos elementos son proporcionados por android, en forma de clases predefinidas a través de la API.
Activities
Las actividades construyen la parte visible de cualquier aplicación. Hay una actividad por cada pantalla, entonces una aplicación con 3 pantallas diferentes implementa 3 actividades diferentes.
Cada actividad debe declararse en el archivo AndroidManifest.xml con la siguiente sintaxis.
<activity android:name="ActivityName">
</activity>
Las actividades no declaradas en el archivo Manifest no se puede mostrar e intentar iniciarlas genera una excepción.
Al igual que las aplicaciones, las actividades tienen un ciclo de vida y necesitan monitorear los eventos del sistema para manejarlas. Las actividades pueden estar en los siguientes estados:
- Activo
- En pausa
- Detenido
- Inactivo.
Estos estados son administrados por android. En consecuencia las actividades pueden implementar los siguientes gestores:
- onCreate
- onSaveInstanceState
- onStart
- onResume
- onRestartInstanceState
- onPause
- onStop
- onRestart
- onDestroy
Una aplicación no debe implementar explícitamente a todos los administradores de eventos, en cuyo caso se toman acciones predeterminadas.
Fragments
Los fragmentos están destinados a encapsular partes de la interfaz para facilitar la reutilización y adaptación a diferentes tamaños de pantalla. Los fragmentos son entidades autónomas en el sentido de que incluyen todos sus componentes necesarios(diseño, botones, etc). Sin embargo, deben integrarse con una actividad para que sea útil.
No es necesario declarar los fragmentos en el archivo Manifest, porque depende de las actividades.
https://developer.android.com/guide/components/fragments?hl=es-419
Inter Process Communication (IPC)
Como ya sabemos, cada proceso de android tiene su propio espacio de direcciones de espacio aislado. El IPC de android se basa en Binder, una implementación personalizada de OpenBinder.
El termino Binder significa muchas cosas diferentes, como:
- Binder Driver: controlador a nivel del Kernel.
- Binder Protocol: protocolo basado en ioctl (input/output control) de bajo nivel utilizado para comunicarse con el Binder Driver
- IBinder Interface: comportamiento que implementan los objetos Binder.
- Binder Object: Implementación genérica de la interfaz IBinder.
- Binder Service: Implementación del objeto Binder: por ejemplo, servicio de ubicación y servicio de sensor.
- Binder Client: Un objeto que usa el servicio Binder.
El framework de Binder incluye un modelo de comunicación cliente-servidor. Para usar el IPC, las aplicaciones llaman métodos IPC de objetos proxy.
Los objetos proxy organizan de forma transparente los parámetros de llamada en un paquete y envían la transacción al servidor Binder. El servidor posee un grupo de sub-procesos para manejar las solicitudes entrantes y entrega de mensajes al objeto destino.
Los servicios que permiten que otras aplicaciones se unan a ellos se denominan servicios vinculados. Estos servicios deben proporcionar una interfaz IBinder a los clientes. Los desarrolladores usan Android Interface Descriptor Language (AIDL), para escribir interfaces de servicio remoto.
ServiceManager es un demonio del sistema que gestiona el registro y la búsqueda de servicios del sistema. Los servicios son agregados con addService
y recuperar con el método estático getService
en android.os.ServiceManager
:
Se puede consultar la lista de servicios del sistema con service list
$ adb shell service list
Found 99 services:
0 carrier_config: [com.android.internal.telephony.ICarrierConfigLoader]
1 phone: [com.android.internal.telephony.ITelephony]
2 isms: [com.android.internal.telephony.ISms]
3 iphonesubinfo: [com.android.internal.telephony.IPhoneSubInfo]
Intents
Intent messaging es un marco de comunicación asíncrono construido sobre binder. Este framework permite la publicación y suscripción de mensajes. Un Intent es un objeto de mensajería que se puede usar para solicitar una acción de otro componente de la aplicación. Aunque los Intents facilitan la comunicación entre componentes de varias maneras, existe 3 casos de uso fundamentales:
- Iniciar un Activity
Un Activity representa una sola pantalla en una aplicación. Se puede comenzar una nueva instancia de la actividad pasando un Intent a startActivity
.
- Iniciar un Service
Un Service es un componente que realiza operaciones en segundo plano, sin una interfaz de usuario. Después de android 5 y superiores, se puede iniciar un servicio con JobScheduler.
- Entregar un Broadcast
Un Broadcast es un mensaje que cualquier aplicación puede recibir. El sistema ofrece transmisión de eventos del sistema, incluido el arranque y la inicializacion de carga.
Los Intents se envían al sistema para realizar una acción determinada, depende del sistema decidir que aplicación o clase realizara el servicio correspondiente.
Intent intent = new Intent(Intent.MY_ACTION, Uri.parse("https://www.owasp.org"));
Un Intent filter esta declarado en el archivo Android Manifest que especifica el tipo de Intent que el componente puede recibir.
Android usa los Intents para transmitir mensajes a aplicaciones, información importante sobre la fuente de alimentación, cambios en la red, etc.
Listaremos algunos Intents enviados por el sistema operativo:
- ACTION_CAMERA_BUTTON
- ACTION_MEDIA_EJECT
- ACTION_NEW_OUTGOING_CALL
- ACTION_TIMEZONE_CHANGED
Para mejorar la seguridad y la privacidad, se utiliza un Local Broadcast Manager para enviar y recibir intents dentro de una aplicación sin enviar al resto del dispositivo. Esto es útil para garantizar que los datos confidenciales y privados no salgan del perímetro de la aplicación(por ejemplo, datos de geolocalizacion).
Broadcast Receivers
O receptores de difusión son componentes que permiten que las aplicaciones reciban notificaciones de otras aplicaciones y del mismo sistema. Generalmente se utilizan para actualizar las interfaces de usuario, iniciar servicios, actualizar contenido y crear notificaciones de usuario.
Ejemplo de una declaración en el AndroidManifest de un Broadcast Receiver.
<receiver android:name=".myReceiver" >
<intent-filter>
<action android:name="com.owasp.myapplication.MY_ACTION" />
</intent-filter>
</receiver>
De acuerdo con Broadcasts Overview, una transmisión se considera implícita si no se dirige específicamente a una aplicación. Después de recibir una transmisión explicita Android enumera todas las aplicaciones que hayan registrado una acción determinada en sus filtros. Si se ha registrado mas de una aplicación para la misma acción, Android pedirá al usuario que seleccione una aplicación.
Para consideraciones de seguridad con respecto al Broadcast Receiver consulte las mejores practicas.
Content Providers
Android usa SQLite para almacenar datos permanentemente. SQLite es una tecnología de almacenamiento de datos relacionales y no requiere mucha potencia de procesamiento, lo que la hace ideal para móviles. SQLite no se ejecuta como un proceso separado es parte de la aplicación. Una base de datos pertenece a una aplicación determinada y solo es accesible para esta aplicación. Sin embargo los proveedores de contenido ofrecen mecanismos para abstraer datos (Incluido bases de datos y archivos). Un Content Provider debe declarar explícitamente en el AndroidManifest que la aplicación compartirá los datos, mientras estos no se declaren, no se exportara y solo podrán ser llamados por la aplicación que los crea.
Los Content Providers ofrecen todas las operaciones regulares de una base de datos (Crear, leer, actualizar y eliminar). Eso significa que cualquier aplicación con los derechos adecuados, puede manipular los datos de otras aplicaciones.
Services
Los servicios (Services) realizan tareas en segundo plano(procesamiento de datos, intentos de inicio, notificaciones ,etc), sin presentar una interfaz de usuario. Sus prioridades del sistema son mas bajas que las aplicaciones activas y mas altas que las aplicaciones inactivas. Por lo tanto es menos probable que se eliminen cuando el sistema necesita recursos, y se pueden configurar para reiniciarse automáticamente cuando haya recursos suficientes.
Permissions
Debido a que las aplicaciones de Android están instaladas en un entorno limitado y al principio no pueden acceder a la información del usuario y a los componentes del sistema (como la cámara y el micrófono). Android proporciona un sistema de permisos predefinido para ciertas tareas que la aplicación puede solicitar.
Por ejemplo, si una aplicación requiere la cámara del teléfono, este debe solicitar el permiso android.permission.CAMERA
. Desde la API 23 en adelante, el usuario debe aprobar los permisos durante la ejecución de la aplicación.
Los permisos de android se clasifican según el nivel de protección:
- Normal
El nivel mas bajo, le da a las aplicaciones acceso a funciones aisladas con un riesgo mínimo para otras aplicaciones. (ejm: android.permission.INTERNET
)
- Dangerous
Este permiso permite que la aplicación realice acciones que podrían afectar la privacidad del usuario o el funcionamiento normal del dispositivo.(ejm android.permission.RECORD_AUDIO
)
- Signature
Este permiso se otorga solo si la aplicación solicitante ha sido firmada con el mismo certificado que la aplicación que declaro el permiso. (ejm android.permission.ACCESS_MOCK_LOCATION
).
- SystemOrSignature
Este permiso se otorga solo a las aplicaciones integradas con el sistema o firmadas con el mismo certificado. (ejm android.permission.ACCESS_DOWNLOAD_MANAGER
).
Solicitud de Permisos
Las aplicaciones pueden solicitar permisos para los niveles de protección normal, peligroso y firmas, al incluir la etiqueta <user-permission/>
en el archivo AndroidManifest. Ejemplo que solicita permiso para leer mensajes SMS.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.permissions.sample" ...>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application>...</application>
</manifest>
Declaración de permisos
Las aplicaciones puede exponer características y contenido a otras aplicaciones instaladas en el sistema. Para restringir el acceso a sus propio componentes, puede usar cualquiera de los permisos predefinidos de Android o definir sus propios permisos. El siguiente ejemplo muestra como una aplicación declara un permiso.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.permissions.sample" ...>
<permission
android:name="com.permissions.sample.ACCESS_USER_INFO"
android:protectionLevel="signature" />
<application>...</application>
</manifest>
El código anterior define un nuevo permiso denominado com.permissions.sample.ACCESS_USER_INFO
, con el nivel de protección signature
. Cualquier componente protegido con este permiso solo podrá ser accesible mediante aplicaciones firmadas con el mismo certificado.
Cumplimiento de permisos en componentes
Los componentes de android se pueden proteger con permisos. Activities, Services, Content Providers y Broadcast Receivers — todos pueden usar el mecanismo de permiso para protegerse. estos permisos se declaran en el archivo AndroidManifest con la etiqueta android:permission
.
<receiver
android:name="com.permissions.sample.AnalyticsReceiver"
android:enabled="true"
android:permission="com.permissions.sample.ACCESS_USER_INFO">
...
</receiver>
Los Content Providers son diferentes, admiten un conjunto separado de permisos para leer, escribir y acceder al contenido.
android:writePermission
,android:readPermission
Los desarrolladores puede establecer permisos separados para leer o escribir.android:permission
permiso general que controla la lectura y escritura al content provider.android:grantUriPermission:"true"
se puede acceder a través de una URI.