- Battery Manager API (
BatteryManager): Obtener información del consumo de batería - Power Profile Data: Consumo de energía por componente (CPU, GPU, pantalla, radio)
- CPU Time Tracking: Usar
android.os.Debugpara medir tiempo de CPU
// Ejemplo básico de lectura de batería
val batteryManager = context.getSystemService(Context. BATTERY_SERVICE) as BatteryManager
val remainingEnergy = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_ENERGY_COUNTER)- TrafficStats API: Monitorear bytes transmitidos/recibidos
- ConnectivityManager: Detectar tipo de conexión (4G, 5G, WiFi)
- Radio State Tracking: Cuando se activa/desactiva la radio
// Ejemplo de TrafficStats
val rxBytes = TrafficStats.getTotalRxBytes()
val txBytes = TrafficStats.getTotalTxBytes()- LocationManager: Frecuencia y duración del uso de GPS
- Accuracy levels: GPS de alta precisión consume más energía
- Update intervals: Rastrear frecuencia de actualizaciones
- Display metrics: Brillo, tiempo de encendido
- Screen State: Mediante
BroadcastReceiverpara detectar cambios - Display technology: OLED vs LCD tienen diferentes consumos
- Acelerómetro, giróscopo, brújula: Consumo de energía variable
- Sensor manager events: Frecuencia de recolección de datos
- WorkManager: Tareas programadas
- Foreground Services: Detectar qué apps ejecutan servicios
- Wake locks: Apps que mantienen el dispositivo despierto
┌─────────────────────────────────────┐
│ Jetpack Compose UI │
│ (Dashboard de estadísticas) │
└────────────┬────────────────────────┘
│
┌────────────▼────────────────────────┐
│ ViewModel / MVVM │
│ (Lógica de presentación) │
└────────────┬────────────────────────┘
│
┌────────────▼────────────────────────┐
│ Repository Pattern │
│ (Abstracción de datos) │
└────────────┬────────────────────────┘
│
┌────────────▼────────────────────────┐
│ Data Layer: │
│ • Battery Manager API │
│ • TrafficStats │
│ • LocationManager │
│ • SensorManager │
│ • Power Usage Statistics │
│ • Local Database (Room) │
└─────────────────────────────────────┘
<!-- Lectura de estadísticas de batería y energía -->
<uses-permission android:name="android.permission. BATTERY_STATS" />
<!-- Acceso a la red -->
<uses-permission android:name="android. permission.ACCESS_NETWORK_STATE" />
<!-- Localización -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android. permission.ACCESS_COARSE_LOCATION" />
<!-- Sensores -->
<uses-permission android:name="android.permission. BODY_SENSORS" />
<!-- Lectura de paquetes instalados -->
<uses-permission android:name="android.permission. QUERY_ALL_PACKAGES" />
<!-- Para monitoreo en background -->
<uses-permission android:name="android.permission. PACKAGE_USAGE_STATS" />- Crear servicio que recopile métricas principales
- Almacenar datos en Room Database
- Crear dashboard simple en Compose
- Mapear consumo de energía a emisiones de carbono
- Usar modelos de consumo de red (bits ≈ CO2)
- Análisis por aplicación/tipo de actividad
- Gráficos de tendencias temporales
- Comparativas entre apps
- Recomendaciones de optimización
Para mapear energía → CO2:
- EPA Carbon Intensity Database: Emisiones por región (grid eléctrico)
- Network Carbon API: Huella de carbono de transmisión de datos
- Device Power Profiles: Consumo específico por modelo de teléfono
📱 PANTALLA (40-50% del consumo)
├─ Scroll continuo (siempre encendida)
├─ Reproducción de videos (variable según resolución)
└─ Transiciones y animaciones de UI
📡 RED (30-40% del consumo)
├─ Descarga de imágenes/videos (high bandwidth)
├─ Streaming de video (H.264/VP9 codecs)
├─ Upload de contenido (si el usuario publica)
└─ Actualizaciones en tiempo real del feed
🎬 GPU/CPU (15-25%)
├─ Decodificación de video
├─ Procesamiento de imagen (filtros)
└─ Renderizado de UI compleja
📍 SENSORES (5-10%)
├─ Acelerómetro (para reels/stories)
├─ Micrófono (si graba videos)
└─ Cámara (captura de fotos/videos)
📡 RED (40-50%)
├─ Sincronización de mensajes (pequeño volumen pero frecuente)
├─ Transmisión de voice notes (comprimidas con Opus codec)
├─ Transmisión de video calls (H.264)
└─ Descarga de archivos/imágenes
📱 PANTALLA (30-40%)
├─ Pantalla encendida durante chats
├─ Notificaciones que activan pantalla
└─ Menor carga que redes sociales
🎤🎵 AUDIO (10-15%)
├─ Codificación de voice notes (Opus)
├─ Reproducción de audio
└─ Video calls (usa mucho si es frecuente)
📍 LOCALIZACIÓN (5%)
├─ Compartir ubicación (si está activo)
└─ Ubicación de contactos cercanos
// Obtener estadísticas de batería por app
fun getAppBatteryUsage(context: Context, packageName: String): Long {
val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
// Para Android 8+, necesitas UsageStatsManager
val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE)
as UsageStatsManager
val currentTime = System.currentTimeMillis()
val oneHourAgo = currentTime - (60 * 60 * 1000)
val queryUsageStats = usageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_HOURLY,
oneHourAgo,
currentTime
)
queryUsageStats.forEach { stat ->
if (stat.packageName == packageName) {
println("App: ${stat.packageName}")
println("Tiempo en foreground: ${stat.totalTimeInForeground}")
println("Últimos: ${stat.lastTimeUsed}")
}
}
}// TrafficStats NO permite filtrar por app directamente
// Necesitas usar eBPF o monitoreo a nivel de sistema
fun getNetworkStatsPerApp(context: Context, packageName: String) {
val networkStatsManager = context.getSystemService(Context.NETWORK_STATS_SERVICE)
as NetworkStatsManager
val currentTime = System.currentTimeMillis()
val oneHourAgo = currentTime - (60 * 60 * 1000)
try {
// Android 6+
val mobileStats = networkStatsManager.queryDetailsForDevice(
ConnectivityManager.TYPE_MOBILE,
"",
oneHourAgo,
currentTime
)
mobileStats.use { bucket ->
while (bucket.hasNextBucket()) {
bucket.getNextBucket()
val uid = bucket.uid
val rxBytes = bucket.rxBytes
val txBytes = bucket.txBytes
// Mapear UID a packageName
println("RX: $rxBytes, TX: $txBytes")
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}// Detectar si Instagram está reproduciendo video
fun monitorDisplayState(context: Context) {
val displayManager = context.getSystemService(Context. DISPLAY_SERVICE) as DisplayManager
displayManager.displays.forEach { display ->
println("Display mode: ${display.mode}")
println("Refresh rate: ${display.mode?. refreshRate}")
println("Resolution: ${display.mode?.physicalWidth} x ${display.mode?.physicalHeight}")
}
}
// Detectar transmisión de video/audio
fun monitorAudioFocus(context: Context) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
// Escuchar cambios en el foco de audio
audioManager.requestAudioFocus(
AudioManager.AUDIOFOCUS_GAIN,
AudioManager.STREAM_MUSIC
)
}
// Detectar uso de cámara
fun monitorCameraUsage(context: Context) {
val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
cameraManager.registerAvailabilityCallback(
object : CameraManager.AvailabilityCallback() {
override fun onCameraAccessPrioritiesChanged() {
super.onCameraAccessPrioritiesChanged()
println("Camera access changed")
}
}
)
}
}Energía Total =
(Tiempo pantalla × Brillo × Tipo LCD/OLED) +
(Datos descargados × Consumo red 4G/5G/WiFi) +
(Datos cargados × Consumo red) +
(Tiempo decodificación video × CPU power) +
(Tiempo GPU × GPU power) +
(Activaciones sensor × Consumo sensor)
Valores típicos:
- 4G: ~0.6 mAh por MB
- 5G: ~0.4 mAh por MB (más eficiente)
- WiFi: ~0.1 mAh por MB (mucho más eficiente)
- Pantalla OLED: 2-3 mA/min (brillo medio)
- Pantalla LCD: 1-2 mA/min (brillo medio)
- Video 1080p @ 30fps: 500-800 mAh/hora
Energía Total =
(Tiempo en foreground × Consumo base) +
(Mensajes enviados/recibidos × Overhead red) +
(Voice notes × Duración × Consumo codec) +
(Video calls × Duración × Consumo H.264) +
(Tiempo compartir ubicación × Consumo GPS)
Valores típicos:
- WhatsApp idle: ~10 mAh/hora
- WhatsApp activo (textos): ~30 mAh/hora
- WhatsApp voice call: ~200-300 mAh/hora
- WhatsApp video call: ~400-600 mAh/hora
@Entity(tableName = "app_metrics")
data class AppMetric(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val packageName: String,
val appName: String,
val timestamp: Long,
// Energía
val batteryUsageEstimate: Float, // mAh
// Red
val dataDownloaded: Long, // bytes
val dataUploaded: Long, // bytes
val networkType: String, // "4G", "5G", "WiFi"
// Pantalla
val screenTimeMs: Long,
val brightnessLevel: Int, // 0-255
// CPU/GPU
val cpuUsagePercent: Float,
val gpuUsagePercent: Float,
// Actividad
val isVideoPlayback: Boolean,
val isAudioPlayback: Boolean,
val isCameraActive: Boolean,
val isGpsActive: Boolean,
// Huella de Carbono
val estimatedCo2Grams: Float
)
@Dao
interface AppMetricDao {
@Insert
suspend fun insert(metric: AppMetric)
@Query("SELECT * FROM app_metrics WHERE packageName = :packageName ORDER BY timestamp DESC")
fun getMetricsForApp(packageName: String): Flow<List<AppMetric>>
}<!-- Para obtener estadísticas detalladas -->
<uses-permission android:name="android.permission. PACKAGE_USAGE_STATS" />
<!-- Para acceso a red detallado -->
<uses-permission android: name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Para detectar instalación de apps -->
<uses-permission android:name="android.permission. QUERY_ALL_PACKAGES" />
<!-- Para monitoreo de sensores -->
<uses-permission android:name="android.permission. BODY_SENSORS" />
<!-- Para cámara y micrófono (si quieres detectar cuando está activa) -->
<uses-permission android:name="android.permission. CAMERA" />
<uses-permission android:name="android.permission. RECORD_AUDIO" />