SDK Android
Cómo medir una app Android con el SDK de Lymen: instalación, opciones, API, pantallas, red, crashes y privacidad.
En esta página
Para qué sirve#
El SDK de Android mide la experiencia real de quienes usan tu app: sesiones, pantallas, tiempo de arranque, errores, cierres inesperados (crashes), apps trabadas (ANR), pedidos de red y eventos de negocio. Lo ves en Aplicaciones.
- Kotlin,
minSdk24. La app tiene que compilar concompileSdk37. - Versión actual: 0.2.1 (artefacto de unos 190 KB).
Cuándo usarlo#
Cuando tenés una app Android propia. Antes, dala de alta en Aplicaciones (tipo Android): ahí obtenés la clave (ly_pub_…) y el código listo para copiar. Si tu app es React Native, mirá SDK React Native.
Instalación#
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
// más el repositorio donde tengas el SDK
}
}
// app/build.gradle.kts
android {
compileOptions {
// Hace falta si minSdk < 26.
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
implementation("app.lymen:lymen-sdk-android:0.2.1")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
}No hace falta configurar R8/ProGuard: el SDK trae sus propias reglas.
Iniciar#
Una sola vez, en Application.onCreate():
class MiApp : Application() {
override fun onCreate() {
super.onCreate()
LymenSdk.iniciar(
this,
Opciones(
sitio = "ly_pub_XXXXXXXXXXXXXXXXXXXXXXXX", // clave pública (no es secreta)
endpoint = "https://<tu-cuenta>-ingesta.lymen.app",
propagarA = listOf("api.tu-empresa.com"),
),
)
}
}iniciar vuelve enseguida: solo instala lo necesario para medir el arranque y la primera pantalla; el resto se arma en segundo plano. Lo que mandes mientras tanto (evento, usuario, error) se guarda y sale después, con su hora original.
Opciones#
| Opción | Para qué sirve | Por defecto | Valores válidos | Impacto de cambiarlo |
|---|---|---|---|---|
sitio |
Clave pública de la app. | — (obligatoria) | ly_pub_… |
Sin ella no se mide. |
endpoint |
Punto de entrada de Lymen. | Un valor de ejemplo que no es el de tu cuenta | https://<tu-cuenta>-ingesta.lymen.app |
Indicalo siempre. Si no, los datos no llegan a tu cuenta. El SDK le agrega las rutas necesarias. |
servicio |
Nombre del servicio. | El paquete de la app | Texto | El servidor lo reemplaza por el nombre de servicio del alta. |
version |
Versión de la app. | versionName |
Texto | Permite comparar versiones. |
entorno |
Entorno. | produccion |
Texto | Separa producción de pruebas. |
propagarA |
Orígenes que reciben traceparent (la marca que une el pedido del celular con la traza del servidor). |
Vacía | api.x.com, api.x.com:8443, *.x.com o https://api.x.com |
Solo a esos orígenes. Se suma a lo configurado en el portal. |
muestreo |
Porción de sesiones que se mandan. | 1.0 |
De 0 a 1 | Costo. Se decide al empezar cada sesión. Si el portal define un muestreo, manda el del portal. |
consentimiento |
Valor inicial. | CONCEDIDO (o lo último que eligió el usuario) |
PENDIENTE, CONCEDIDO, DENEGADO |
Legal y privacidad. PENDIENTE junta en memoria sin mandar; DENEGADO no manda nada y borra lo pendiente y la cola en disco. Si pedís permiso en tu app, iniciá en PENDIENTE. |
capturarClics |
Registra los toques. | false |
true / false |
Privacidad. Guarda el id del recurso tocado, nunca el texto. El portal puede mandar sobre este valor. |
vistasAutomaticas |
Detecta las pantallas (Activity y Fragment). | true |
true / false |
En false, marcá las pantallas a mano. |
depuracion |
Escribe en logcat con la etiqueta lymen. |
false |
true / false |
Solo desarrollo. |
API#
LymenSdk.usuario("id-del-usuario") // se manda el hash SHA-256; null lo borra
LymenSdk.evento("turno.reservado", mapOf("monto" to 15000, "moneda" to "ARS"))
LymenSdk.error(excepcion, mapOf("pantalla.accion" to "pagar")) // error manejado
LymenSdk.vista("Pago") // pantalla manual
LymenSdk.consentimiento(Consentimiento.DENEGADO)
LymenSdk.log(NivelLog.WARN, "reintento del pago") // apagado salvo que el portal prenda los mensajes
LymenSdk.sesionActual() // id de sesión, para mandarlo a tu backend
LymenSdk.enviarAhora()Los eventos de negocio se llaman entidad.accion (minúsculas, números y _); si no, se ignoran. Mandá un mismo evento desde la app o desde el backend, nunca desde los dos, o se cuenta doble.
Pantallas#
- Activity y Fragment: automáticas. Si una Activity solo aloja fragments, cuenta el Fragment.
- Jetpack Compose: poné
VistaLymen("Nombre")al principio de cada pantalla y marcá la Activity con@SinVistaAutomaticapara que no cuente doble. - Manual:
LymenSdk.vista("Nombre").
Red (OkHttp)#
val cliente = OkHttpClient.Builder()
.addInterceptor(LymenOkHttp.interceptor())
.build()Cada pedido es un span con los atributos HTTP estándar. traceparent se agrega solo a los orígenes de propagarA.
Qué mide#
| Dato | Detalle |
|---|---|
| Sesión | Se renueva a los 30 minutos sin actividad o a las 4 horas. Sigue si la app se reinicia antes. Registra el origen: directo, enlace (deep link) o notificación. |
| Inicio de la app | En frío (desde que arranca el proceso), tibio (proceso vivo, Activity nueva) y caliente (vuelve a primer plano), hasta el primer cuadro. |
| Errores | Los que mandes con error(): tipo, mensaje, stack (hasta 8 KB) y huella para agrupar. |
| Crashes | Se guardan en disco antes de que la app se cierre y salen en el próximo arranque. |
| ANR | Cuando el hilo principal no responde por 5 segundos o más. Si el sistema cierra la app, sale en el próximo arranque. |
| Pedidos de red | Con el interceptor de OkHttp. |
| Clics | Solo si los activás. |
Envío y reintentos#
- Datos comprimidos, en lotes de hasta 50 elementos, cada 5 segundos o al juntar 50, y al pasar a segundo plano.
- Cola en disco con tope de 5 MB: si se llena, se descartan los lotes más viejos.
- Ante errores de red o del servidor se reintenta con espera creciente (5 s, 10 s, 20 s… hasta 5 minutos). Si la clave es inválida o la aplicación está pausada en el portal, se frenan los envíos 10 minutos.
Privacidad#
- Las reglas de Privacidad bajan del servidor (al iniciar y cada 10 minutos) y se aplican en el celular antes de mandar. El servidor las vuelve a aplicar.
- Sin reglas descargadas, se usan las de respaldo: DNI, email, tarjetas y CUIT/CUIL.
- No se captura el valor de ningún campo de texto y no se graban sesiones.
user.idsale siempre hasheado. - Desde el portal podés apagar tipos de dato (vistas, tiempos, errores, red, clics, sesiones, logs): lo apagado no sale del celular. Los logs vienen apagados.
Problemas comunes#
| Síntoma | Qué hacer |
|---|---|
| No llegan datos | Revisá sitio y endpoint; activá depuracion = true y mirá logcat con la etiqueta lymen. Confirmá que la app esté con Recibir datos en el portal. |
Error de compilación por compileSdk |
La app tiene que compilar con compileSdk 37. |
La app compila con minSdk menor que 26 y falla |
Activá el desugaring (isCoreLibraryDesugaringEnabled = true) y la dependencia coreLibraryDesugaring. |
| No veo los crashes enseguida | Se envían en el siguiente arranque de la app. |
| Se cuentan doble los eventos | Mandalos solo desde un lado: la app o el backend. |