Skip to content

Battery Optimization for Mobile Applications

Introduction to Mobile Battery Management

Battery optimization is a critical aspect of mobile application development that directly impacts user experience and app retention. Modern mobile operating systems implement sophisticated power management systems, and applications must work within these constraints while providing optimal functionality.

Battery Management Architecture

Platform-Specific Battery Optimization

Android Battery Management

Battery State Monitoring

kotlin
class BatteryOptimizationManager(private val context: Context) {
    private val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
    private val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
    private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    
    private val batteryReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                Intent.ACTION_BATTERY_CHANGED -> handleBatteryChanged(intent)
                Intent.ACTION_POWER_CONNECTED -> handlePowerConnected()
                Intent.ACTION_POWER_DISCONNECTED -> handlePowerDisconnected()
                PowerManager.ACTION_POWER_SAVE_MODE_CHANGED -> handlePowerSaveModeChanged()
            }
        }
    }
    
    fun initialize() {
        val filter = IntentFilter().apply {
            addAction(Intent.ACTION_BATTERY_CHANGED)
            addAction(Intent.ACTION_POWER_CONNECTED)
            addAction(Intent.ACTION_POWER_DISCONNECTED)
            addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
        }
        context.registerReceiver(batteryReceiver, filter)
    }
    
    private fun handleBatteryChanged(intent: Intent) {
        val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
        val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
        val batteryPct = level * 100 / scale.toFloat()
        
        val status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
        val isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                        status == BatteryManager.BATTERY_STATUS_FULL
        
        val health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, -1)
        val temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1) / 10.0
        
        updateBatteryOptimization(
            BatteryState(
                level = batteryPct,
                isCharging = isCharging,
                health = health,
                temperature = temperature
            )
        )
    }
    
    private fun updateBatteryOptimization(batteryState: BatteryState) {
        when {
            batteryState.level < 15 -> enableUltraLowPowerMode()
            batteryState.level < 30 -> enableLowPowerMode()
            batteryState.level < 50 -> enableBalancedMode()
            else -> enableNormalMode()
        }
        
        if (powerManager.isPowerSaveMode) {
            enableSystemPowerSaveOptimizations()
        }
        
        // Thermal throttling
        if (batteryState.temperature > 40) { // 40°C
            enableThermalThrottling()
        }
    }
    
    private fun enableUltraLowPowerMode() {
        // Most aggressive power saving
        BackgroundTaskManager.pauseNonCriticalTasks()
        NetworkManager.enableDataSavingMode()
        UIManager.reduceAnimations()
        LocationManager.disableLocationTracking()
        CacheManager.clearNonEssentialCaches()
        
        // Reduce CPU frequency if possible
        reduceBackgroundActivity(0.1f) // 10% of normal activity
    }
    
    private fun enableLowPowerMode() {
        // Significant power saving
        BackgroundTaskManager.limitBackgroundTasks()
        NetworkManager.enableRequestCoalescing()
        UIManager.reduceRefreshRate()
        LocationManager.enableLowPowerLocationMode()
        
        reduceBackgroundActivity(0.3f) // 30% of normal activity
    }
    
    private fun enableBalancedMode() {
        // Moderate power saving
        BackgroundTaskManager.enableIntelligentScheduling()
        NetworkManager.optimizeNetworkCalls()
        UIManager.enableSmartRefresh()
        
        reduceBackgroundActivity(0.7f) // 70% of normal activity
    }
    
    private fun enableNormalMode() {
        // Full functionality
        BackgroundTaskManager.enableAllTasks()
        NetworkManager.enableFullNetworking()
        UIManager.enableFullAnimations()
        LocationManager.enableFullLocationTracking()
        
        reduceBackgroundActivity(1.0f) // 100% normal activity
    }
    
    private fun reduceBackgroundActivity(ratio: Float) {
        SchedulerManager.setActivityRatio(ratio)
        TimerManager.adjustTimerIntervals(ratio)
        WorkManager.setBackgroundWorkRatio(ratio)
    }
}

data class BatteryState(
    val level: Float,
    val isCharging: Boolean,
    val health: Int,
    val temperature: Double
)

Background Task Optimization

kotlin
class BackgroundTaskOptimizer {
    private val taskQueue = PriorityQueue<OptimizedTask>(compareBy { it.priority })
    private val executionLimiter = ExecutionLimiter()
    
    enum class TaskPriority {
        CRITICAL,    // User-initiated, immediate
        HIGH,        // Important but can be delayed
        MEDIUM,      // Background sync, prefetching
        LOW,         // Analytics, cleanup
        DEFERRED     // Non-essential maintenance
    }
    
    fun scheduleTask(task: OptimizedTask) {
        // Check battery constraints
        if (!canExecuteTask(task)) {
            deferTask(task)
            return
        }
        
        // Check execution limits
        if (!executionLimiter.canExecute(task)) {
            queueTask(task)
            return
        }
        
        executeTask(task)
    }
    
    private fun canExecuteTask(task: OptimizedTask): Boolean {
        val batteryLevel = getBatteryLevel()
        val isPowerSaveMode = isPowerSaveMode()
        val isCharging = isCharging()
        
        return when (task.priority) {
            TaskPriority.CRITICAL -> true
            TaskPriority.HIGH -> batteryLevel > 15 || isCharging
            TaskPriority.MEDIUM -> (batteryLevel > 30 && !isPowerSaveMode) || isCharging
            TaskPriority.LOW -> (batteryLevel > 50 && !isPowerSaveMode) || isCharging
            TaskPriority.DEFERRED -> isCharging && batteryLevel > 80
        }
    }
    
    private fun executeTask(task: OptimizedTask) {
        CoroutineScope(Dispatchers.Default).launch {
            try {
                // Monitor resource usage during execution
                val resourceMonitor = ResourceMonitor()
                resourceMonitor.startMonitoring()
                
                // Execute with timeout
                withTimeout(task.maxExecutionTime) {
                    task.execute()
                }
                
                val resourceUsage = resourceMonitor.getUsage()
                updateTaskStatistics(task, resourceUsage)
                
            } catch (e: Exception) {
                handleTaskFailure(task, e)
            }
        }
    }
    
    private class ExecutionLimiter {
        private val executionCounts = mutableMapOf<TaskPriority, Int>()
        private val resetTimer = Timer()
        
        init {
            // Reset execution counts every hour
            resetTimer.scheduleAtFixedRate(object : TimerTask() {
                override fun run() {
                    executionCounts.clear()
                }
            }, 0, 3600000) // 1 hour
        }
        
        fun canExecute(task: OptimizedTask): Boolean {
            val currentCount = executionCounts[task.priority] ?: 0
            val limit = getExecutionLimit(task.priority)
            
            return currentCount < limit
        }
        
        private fun getExecutionLimit(priority: TaskPriority): Int {
            return when (priority) {
                TaskPriority.CRITICAL -> Int.MAX_VALUE
                TaskPriority.HIGH -> 100
                TaskPriority.MEDIUM -> 50
                TaskPriority.LOW -> 20
                TaskPriority.DEFERRED -> 5
            }
        }
    }
}

data class OptimizedTask(
    val id: String,
    val priority: BackgroundTaskOptimizer.TaskPriority,
    val maxExecutionTime: Long,
    val requiredResources: Set<Resource>,
    val execute: suspend () -> Unit
)

enum class Resource {
    NETWORK,
    GPS,
    CAMERA,
    MICROPHONE,
    STORAGE,
    COMPUTE
}

iOS Battery Optimization

Power Management Implementation

swift
import UIKit
import Foundation

class BatteryOptimizationManager: NSObject {
    private let processInfo = ProcessInfo.processInfo
    private var batteryMonitoringTimer: Timer?
    private var currentPowerState: PowerState = .normal
    
    enum PowerState {
        case normal
        case balanced
        case lowPower
        case critical
    }
    
    override init() {
        super.init()
        setupBatteryMonitoring()
    }
    
    private func setupBatteryMonitoring() {
        UIDevice.current.isBatteryMonitoringEnabled = true
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(batteryLevelChanged),
            name: UIDevice.batteryLevelDidChangeNotification,
            object: nil
        )
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(batteryStateChanged),
            name: UIDevice.batteryStateDidChangeNotification,
            object: nil
        )
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(powerModeChanged),
            name: .NSProcessInfoPowerStateDidChange,
            object: nil
        )
        
        // Start periodic monitoring
        startPeriodicMonitoring()
    }
    
    private func startPeriodicMonitoring() {
        batteryMonitoringTimer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { _ in
            self.evaluatePowerState()
        }
    }
    
    @objc private func batteryLevelChanged() {
        evaluatePowerState()
    }
    
    @objc private func batteryStateChanged() {
        evaluatePowerState()
    }
    
    @objc private func powerModeChanged() {
        evaluatePowerState()
    }
    
    private func evaluatePowerState() {
        let batteryLevel = UIDevice.current.batteryLevel
        let batteryState = UIDevice.current.batteryState
        let isLowPowerMode = processInfo.isLowPowerModeEnabled
        let thermalState = processInfo.thermalState
        
        let newPowerState = determinePowerState(
            batteryLevel: batteryLevel,
            batteryState: batteryState,
            isLowPowerMode: isLowPowerMode,
            thermalState: thermalState
        )
        
        if newPowerState != currentPowerState {
            currentPowerState = newPowerState
            applyPowerOptimizations(newPowerState)
        }
    }
    
    private func determinePowerState(
        batteryLevel: Float,
        batteryState: UIDevice.BatteryState,
        isLowPowerMode: Bool,
        thermalState: ProcessInfo.ThermalState
    ) -> PowerState {
        
        // Critical conditions
        if batteryLevel < 0.1 || thermalState == .critical {
            return .critical
        }
        
        // Low power conditions
        if isLowPowerMode || batteryLevel < 0.2 || thermalState == .serious {
            return .lowPower
        }
        
        // Balanced conditions
        if batteryLevel < 0.5 || thermalState == .fair {
            return .balanced
        }
        
        return .normal
    }
    
    private func applyPowerOptimizations(_ powerState: PowerState) {
        switch powerState {
        case .critical:
            applyCriticalOptimizations()
        case .lowPower:
            applyLowPowerOptimizations()
        case .balanced:
            applyBalancedOptimizations()
        case .normal:
            applyNormalOptimizations()
        }
    }
    
    private func applyCriticalOptimizations() {
        // Suspend all non-essential operations
        BackgroundTaskManager.shared.suspendAllTasks()
        NetworkManager.shared.enableUltraDataSaving()
        LocationManager.shared.disableLocationTracking()
        AnimationManager.shared.disableAnimations()
        
        // Reduce screen brightness
        UIScreen.main.brightness = max(UIScreen.main.brightness * 0.5, 0.1)
        
        // Minimize refresh rates
        if #available(iOS 15.0, *) {
            // Request lower refresh rate
            UIApplication.shared.windows.first?.rootViewController?.view.preferredFramesPerSecond = 30
        }
    }
    
    private func applyLowPowerOptimizations() {
        BackgroundTaskManager.shared.limitBackgroundTasks()
        NetworkManager.shared.enableRequestCoalescing()
        LocationManager.shared.enableLowPowerMode()
        AnimationManager.shared.reduceAnimations()
        
        // Reduce background app refresh
        if #available(iOS 14.0, *) {
            // Minimize background processing
        }
    }
    
    private func applyBalancedOptimizations() {
        BackgroundTaskManager.shared.enableIntelligentScheduling()
        NetworkManager.shared.optimizeNetworkUsage()
        LocationManager.shared.enableBalancedMode()
        AnimationManager.shared.enableSmartAnimations()
    }
    
    private func applyNormalOptimizations() {
        BackgroundTaskManager.shared.enableAllTasks()
        NetworkManager.shared.enableFullNetworking()
        LocationManager.shared.enableFullTracking()
        AnimationManager.shared.enableFullAnimations()
    }
}

// Battery-aware background task scheduling
class BatteryAwareTaskScheduler {
    private var scheduledTasks: [String: BGTask] = [:]
    
    func scheduleTask(
        identifier: String,
        earliestBeginDate: Date? = nil,
        requiresNetworkConnectivity: Bool = false,
        requiresExternalPower: Bool = false
    ) {
        let request: BGTaskRequest
        
        if requiresExternalPower {
            // Use BGAppRefreshTaskRequest for power-dependent tasks
            let appRefreshRequest = BGAppRefreshTaskRequest(identifier: identifier)
            appRefreshRequest.earliestBeginDate = earliestBeginDate
            request = appRefreshRequest
        } else {
            // Use BGProcessingTaskRequest for general background tasks
            let processingRequest = BGProcessingTaskRequest(identifier: identifier)
            processingRequest.requiresNetworkConnectivity = requiresNetworkConnectivity
            processingRequest.requiresExternalPower = requiresExternalPower
            processingRequest.earliestBeginDate = earliestBeginDate
            request = processingRequest
        }
        
        do {
            try BGTaskScheduler.shared.submit(request)
        } catch {
            print("Could not schedule task: \(error)")
        }
    }
    
    func handleBackgroundTask(_ task: BGTask) {
        // Schedule the next iteration
        scheduleTask(identifier: task.identifier)
        
        // Create an operation queue for the task
        let queue = OperationQueue()
        queue.maxConcurrentOperationCount = 1
        
        // Add the task operation
        let operation = createTaskOperation(for: task)
        queue.addOperation(operation)
        
        // Handle task expiration
        task.expirationHandler = {
            queue.cancelAllOperations()
            task.setTaskCompleted(success: false)
        }
        
        // Notify when the task is complete
        operation.completionBlock = {
            task.setTaskCompleted(success: !operation.isCancelled)
        }
    }
    
    private func createTaskOperation(for task: BGTask) -> Operation {
        return BlockOperation {
            // Perform the background work
            self.performBackgroundWork(for: task)
        }
    }
    
    private func performBackgroundWork(for task: BGTask) {
        // Check battery level before proceeding
        let batteryLevel = UIDevice.current.batteryLevel
        let isCharging = UIDevice.current.batteryState == .charging
        
        if batteryLevel < 0.2 && !isCharging {
            // Skip non-critical tasks on low battery
            return
        }
        
        // Perform the actual work based on task type
        switch task.identifier {
        case "com.app.background-sync":
            performBackgroundSync()
        case "com.app.data-cleanup":
            performDataCleanup()
        case "com.app.cache-preload":
            if batteryLevel > 0.5 || isCharging {
                performCachePreload()
            }
        default:
            break
        }
    }
    
    private func performBackgroundSync() {
        // Implement background sync with battery awareness
    }
    
    private func performDataCleanup() {
        // Implement data cleanup
    }
    
    private func performCachePreload() {
        // Implement cache preloading only when battery allows
    }
}

React Native Battery Optimization

Cross-Platform Battery Management

typescript
import { DeviceEventEmitter, NativeModules, Platform } from 'react-native';
import DeviceInfo from 'react-native-device-info';

interface BatteryInfo {
  level: number;
  isCharging: boolean;
  isLowPowerMode?: boolean;
}

class BatteryOptimizationService {
  private batteryInfo: BatteryInfo = { level: 1, isCharging: false };
  private optimizationLevel: 'normal' | 'balanced' | 'aggressive' = 'normal';
  private listeners: Set<(info: BatteryInfo) => void> = new Set();
  
  async initialize(): Promise<void> {
    // Get initial battery info
    await this.updateBatteryInfo();
    
    // Set up battery monitoring
    this.setupBatteryMonitoring();
    
    // Start periodic checks
    this.startPeriodicMonitoring();
  }
  
  private async updateBatteryInfo(): Promise<void> {
    try {
      const [level, isCharging] = await Promise.all([
        DeviceInfo.getBatteryLevel(),
        DeviceInfo.isBatteryCharging(),
      ]);
      
      let isLowPowerMode = false;
      if (Platform.OS === 'ios') {
        isLowPowerMode = await DeviceInfo.isPowerSaveMode();
      }
      
      this.batteryInfo = {
        level,
        isCharging,
        isLowPowerMode,
      };
      
      this.updateOptimizationLevel();
      this.notifyListeners();
      
    } catch (error) {
      console.error('Failed to update battery info:', error);
    }
  }
  
  private setupBatteryMonitoring(): void {
    if (Platform.OS === 'android') {
      // Android battery monitoring
      DeviceEventEmitter.addListener('batteryChanged', (batteryInfo) => {
        this.batteryInfo = {
          level: batteryInfo.level / 100,
          isCharging: batteryInfo.isCharging,
        };
        this.updateOptimizationLevel();
        this.notifyListeners();
      });
    }
    
    // iOS monitoring through native module
    if (Platform.OS === 'ios') {
      DeviceEventEmitter.addListener('batteryStateChanged', (batteryInfo) => {
        this.batteryInfo = batteryInfo;
        this.updateOptimizationLevel();
        this.notifyListeners();
      });
    }
  }
  
  private startPeriodicMonitoring(): void {
    setInterval(() => {
      this.updateBatteryInfo();
    }, 60000); // Check every minute
  }
  
  private updateOptimizationLevel(): void {
    const { level, isCharging, isLowPowerMode } = this.batteryInfo;
    
    if (level < 0.15 || isLowPowerMode) {
      this.optimizationLevel = 'aggressive';
    } else if (level < 0.5 && !isCharging) {
      this.optimizationLevel = 'balanced';
    } else {
      this.optimizationLevel = 'normal';
    }
    
    this.applyOptimizations();
  }
  
  private applyOptimizations(): void {
    switch (this.optimizationLevel) {
      case 'aggressive':
        this.applyAggressiveOptimizations();
        break;
      case 'balanced':
        this.applyBalancedOptimizations();
        break;
      case 'normal':
        this.applyNormalOptimizations();
        break;
    }
  }
  
  private applyAggressiveOptimizations(): void {
    // Reduce background sync frequency
    BackgroundSyncManager.setUpdateInterval(300000); // 5 minutes
    
    // Disable non-essential features
    LocationService.enablePowerSaveMode();
    AnimationService.disableAnimations();
    
    // Reduce image quality
    ImageCacheManager.setQuality('low');
    
    // Minimize network requests
    NetworkManager.enableAggressiveCoalescing();
  }
  
  private applyBalancedOptimizations(): void {
    // Moderate background sync
    BackgroundSyncManager.setUpdateInterval(120000); // 2 minutes
    
    // Reduce location accuracy
    LocationService.enableBalancedMode();
    
    // Optimize animations
    AnimationService.enableLightAnimations();
    
    // Medium image quality
    ImageCacheManager.setQuality('medium');
    
    // Enable request coalescing
    NetworkManager.enableRequestCoalescing();
  }
  
  private applyNormalOptimizations(): void {
    // Normal operation
    BackgroundSyncManager.setUpdateInterval(30000); // 30 seconds
    LocationService.enableFullAccuracy();
    AnimationService.enableFullAnimations();
    ImageCacheManager.setQuality('high');
    NetworkManager.enableFullNetworking();
  }
  
  addBatteryListener(listener: (info: BatteryInfo) => void): void {
    this.listeners.add(listener);
  }
  
  removeBatteryListener(listener: (info: BatteryInfo) => void): void {
    this.listeners.delete(listener);
  }
  
  private notifyListeners(): void {
    this.listeners.forEach(listener => listener(this.batteryInfo));
  }
  
  getBatteryInfo(): BatteryInfo {
    return { ...this.batteryInfo };
  }
  
  getOptimizationLevel(): string {
    return this.optimizationLevel;
  }
}

// Network optimization based on battery
class BatteryAwareNetworkManager {
  private requestQueue: NetworkRequest[] = [];
  private batchTimer: NodeJS.Timeout | null = null;
  private batteryService: BatteryOptimizationService;
  
  constructor(batteryService: BatteryOptimizationService) {
    this.batteryService = batteryService;
    this.batteryService.addBatteryListener(this.onBatteryChanged.bind(this));
  }
  
  private onBatteryChanged(batteryInfo: BatteryInfo): void {
    if (batteryInfo.level < 0.2 && !batteryInfo.isCharging) {
      // Enable aggressive request batching
      this.enableAggressiveBatching();
    } else if (batteryInfo.level < 0.5) {
      // Enable moderate batching
      this.enableModerateBatching();
    } else {
      // Normal operation
      this.enableNormalOperation();
    }
  }
  
  private enableAggressiveBatching(): void {
    // Batch requests for 10 seconds
    this.setBatchInterval(10000);
  }
  
  private enableModerateBatching(): void {
    // Batch requests for 3 seconds
    this.setBatchInterval(3000);
  }
  
  private enableNormalOperation(): void {
    // Minimal batching (1 second)
    this.setBatchInterval(1000);
  }
  
  private setBatchInterval(interval: number): void {
    if (this.batchTimer) {
      clearInterval(this.batchTimer);
    }
    
    this.batchTimer = setInterval(() => {
      this.processBatchedRequests();
    }, interval);
  }
  
  queueRequest(request: NetworkRequest): void {
    this.requestQueue.push(request);
    
    // Process immediately if not in power save mode
    const batteryInfo = this.batteryService.getBatteryInfo();
    if (batteryInfo.level > 0.5 || batteryInfo.isCharging) {
      this.processBatchedRequests();
    }
  }
  
  private async processBatchedRequests(): Promise<void> {
    if (this.requestQueue.length === 0) return;
    
    const batch = [...this.requestQueue];
    this.requestQueue = [];
    
    // Group similar requests
    const groupedRequests = this.groupSimilarRequests(batch);
    
    for (const group of groupedRequests) {
      await this.executeBatchRequest(group);
    }
  }
  
  private groupSimilarRequests(requests: NetworkRequest[]): NetworkRequest[][] {
    const groups = new Map<string, NetworkRequest[]>();
    
    requests.forEach(request => {
      const key = `${request.method}-${request.baseUrl}`;
      if (!groups.has(key)) {
        groups.set(key, []);
      }
      groups.get(key)!.push(request);
    });
    
    return Array.from(groups.values());
  }
  
  private async executeBatchRequest(requests: NetworkRequest[]): Promise<void> {
    try {
      if (requests.length === 1) {
        await requests[0].execute();
      } else {
        // Execute as batch request
        await this.executeBatch(requests);
      }
    } catch (error) {
      console.error('Batch request failed:', error);
      // Retry individual requests
      for (const request of requests) {
        this.queueRequest(request);
      }
    }
  }
  
  private async executeBatch(requests: NetworkRequest[]): Promise<void> {
    // Implementation for batch API call
    const batchPayload = {
      requests: requests.map(req => ({
        id: req.id,
        method: req.method,
        url: req.url,
        data: req.data,
      })),
    };
    
    const response = await fetch('/api/batch', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(batchPayload),
    });
    
    const results = await response.json();
    
    // Process batch results
    results.responses.forEach((result: any) => {
      const request = requests.find(req => req.id === result.id);
      if (request) {
        if (result.success) {
          request.resolve(result.data);
        } else {
          request.reject(new Error(result.error));
        }
      }
    });
  }
}

interface NetworkRequest {
  id: string;
  method: string;
  baseUrl: string;
  url: string;
  data?: any;
  execute: () => Promise<any>;
  resolve: (data: any) => void;
  reject: (error: Error) => void;
}

Flutter Battery Optimization

Comprehensive Battery Management

dart
import 'package:battery_plus/battery_plus.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'dart:async';
import 'dart:io';

enum PowerState {
  normal,
  balanced,
  lowPower,
  critical,
}

class BatteryOptimizationService {
  static final BatteryOptimizationService _instance = BatteryOptimizationService._internal();
  factory BatteryOptimizationService() => _instance;
  BatteryOptimizationService._internal();
  
  final Battery _battery = Battery();
  PowerState _currentPowerState = PowerState.normal;
  StreamSubscription<BatteryState>? _batterySubscription;
  Timer? _batteryCheckTimer;
  
  final StreamController<PowerState> _powerStateController = StreamController<PowerState>.broadcast();
  Stream<PowerState> get powerStateStream => _powerStateController.stream;
  
  int _batteryLevel = 100;
  bool _isCharging = false;
  bool _isLowPowerMode = false;
  
  Future<void> initialize() async {
    await _updateBatteryInfo();
    _startBatteryMonitoring();
    _startPeriodicChecks();
  }
  
  void dispose() {
    _batterySubscription?.cancel();
    _batteryCheckTimer?.cancel();
    _powerStateController.close();
  }
  
  Future<void> _updateBatteryInfo() async {
    try {
      _batteryLevel = await _battery.batteryLevel;
      final batteryState = await _battery.batteryState;
      _isCharging = batteryState == BatteryState.charging;
      
      if (Platform.isIOS) {
        _isLowPowerMode = await _battery.isInBatterySaveMode;
      }
      
      _evaluatePowerState();
    } catch (e) {
      print('Failed to update battery info: $e');
    }
  }
  
  void _startBatteryMonitoring() {
    _batterySubscription = _battery.onBatteryStateChanged.listen((BatteryState state) {
      _isCharging = state == BatteryState.charging;
      _evaluatePowerState();
    });
  }
  
  void _startPeriodicChecks() {
    _batteryCheckTimer = Timer.periodic(const Duration(minutes: 1), (_) {
      _updateBatteryInfo();
    });
  }
  
  void _evaluatePowerState() {
    PowerState newState;
    
    if (_batteryLevel < 10 || (_isLowPowerMode && _batteryLevel < 20)) {
      newState = PowerState.critical;
    } else if (_batteryLevel < 20 || _isLowPowerMode) {
      newState = PowerState.lowPower;
    } else if (_batteryLevel < 50 && !_isCharging) {
      newState = PowerState.balanced;
    } else {
      newState = PowerState.normal;
    }
    
    if (newState != _currentPowerState) {
      _currentPowerState = newState;
      _powerStateController.add(_currentPowerState);
      _applyOptimizations(_currentPowerState);
    }
  }
  
  void _applyOptimizations(PowerState state) {
    switch (state) {
      case PowerState.critical:
        _applyCriticalOptimizations();
        break;
      case PowerState.lowPower:
        _applyLowPowerOptimizations();
        break;
      case PowerState.balanced:
        _applyBalancedOptimizations();
        break;
      case PowerState.normal:
        _applyNormalOptimizations();
        break;
    }
  }
  
  void _applyCriticalOptimizations() {
    // Suspend all non-essential operations
    BackgroundTaskManager.instance.suspendAllTasks();
    NetworkManager.instance.enableUltraDataSaving();
    LocationService.instance.disableLocationTracking();
    
    // Reduce refresh rates
    FrameRateManager.instance.setTargetFrameRate(30);
    
    // Clear caches
    CacheManager.instance.clearNonEssentialCaches();
  }
  
  void _applyLowPowerOptimizations() {
    BackgroundTaskManager.instance.limitBackgroundTasks();
    NetworkManager.instance.enableRequestCoalescing();
    LocationService.instance.enableLowPowerMode();
    
    // Reduce animation duration
    AnimationManager.instance.setDurationMultiplier(0.5);
  }
  
  void _applyBalancedOptimizations() {
    BackgroundTaskManager.instance.enableIntelligentScheduling();
    NetworkManager.instance.optimizeNetworkUsage();
    LocationService.instance.enableBalancedMode();
    
    AnimationManager.instance.setDurationMultiplier(0.8);
  }
  
  void _applyNormalOptimizations() {
    BackgroundTaskManager.instance.enableAllTasks();
    NetworkManager.instance.enableFullNetworking();
    LocationService.instance.enableFullTracking();
    
    FrameRateManager.instance.setTargetFrameRate(60);
    AnimationManager.instance.setDurationMultiplier(1.0);
  }
  
  PowerState get currentPowerState => _currentPowerState;
  int get batteryLevel => _batteryLevel;
  bool get isCharging => _isCharging;
  bool get isLowPowerMode => _isLowPowerMode;
}

// Battery-aware widget that adapts its behavior
class BatteryAwareWidget extends StatefulWidget {
  final Widget child;
  final Widget? lowPowerChild;
  final Widget? criticalPowerChild;
  
  const BatteryAwareWidget({
    Key? key,
    required this.child,
    this.lowPowerChild,
    this.criticalPowerChild,
  }) : super(key: key);
  
  @override
  _BatteryAwareWidgetState createState() => _BatteryAwareWidgetState();
}

class _BatteryAwareWidgetState extends State<BatteryAwareWidget> {
  late StreamSubscription<PowerState> _powerStateSubscription;
  PowerState _currentPowerState = PowerState.normal;
  
  @override
  void initState() {
    super.initState();
    _currentPowerState = BatteryOptimizationService().currentPowerState;
    _powerStateSubscription = BatteryOptimizationService()
        .powerStateStream
        .listen((PowerState state) {
      if (mounted) {
        setState(() {
          _currentPowerState = state;
        });
      }
    });
  }
  
  @override
  void dispose() {
    _powerStateSubscription.cancel();
    super.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    switch (_currentPowerState) {
      case PowerState.critical:
        return widget.criticalPowerChild ?? 
               widget.lowPowerChild ?? 
               _buildSimplifiedWidget();
      case PowerState.lowPower:
        return widget.lowPowerChild ?? _buildOptimizedWidget();
      case PowerState.balanced:
        return _buildOptimizedWidget();
      case PowerState.normal:
        return widget.child;
    }
  }
  
  Widget _buildSimplifiedWidget() {
    // Return minimal UI for critical battery state
    return Container(
      padding: const EdgeInsets.all(16),
      child: const Text(
        'Low Battery Mode',
        style: TextStyle(fontSize: 16),
      ),
    );
  }
  
  Widget _buildOptimizedWidget() {
    // Return optimized version of the widget
    return AnimatedContainer(
      duration: const Duration(milliseconds: 200),
      child: widget.child,
    );
  }
}

// Background task manager with battery awareness
class BatteryAwareTaskManager {
  static final BatteryAwareTaskManager _instance = BatteryAwareTaskManager._internal();
  factory BatteryAwareTaskManager() => _instance;
  BatteryAwareTaskManager._internal();
  
  final List<BatteryAwareTask> _tasks = [];
  Timer? _executionTimer;
  
  void initialize() {
    BatteryOptimizationService().powerStateStream.listen(_onPowerStateChanged);
    _startTaskExecution();
  }
  
  void scheduleTask(BatteryAwareTask task) {
    _tasks.add(task);
  }
  
  void _onPowerStateChanged(PowerState state) {
    switch (state) {
      case PowerState.critical:
        _pauseAllTasks();
        break;
      case PowerState.lowPower:
        _pauseLowPriorityTasks();
        break;
      case PowerState.balanced:
        _resumeHighPriorityTasks();
        break;
      case PowerState.normal:
        _resumeAllTasks();
        break;
    }
  }
  
  void _startTaskExecution() {
    _executionTimer = Timer.periodic(const Duration(seconds: 10), (_) {
      _executePendingTasks();
    });
  }
  
  void _executePendingTasks() {
    final powerState = BatteryOptimizationService().currentPowerState;
    final isCharging = BatteryOptimizationService().isCharging;
    
    for (final task in _tasks.where((t) => t.shouldExecute(powerState, isCharging))) {
      task.execute();
    }
  }
  
  void _pauseAllTasks() {
    for (final task in _tasks) {
      task.pause();
    }
  }
  
  void _pauseLowPriorityTasks() {
    for (final task in _tasks.where((t) => t.priority == TaskPriority.low)) {
      task.pause();
    }
  }
  
  void _resumeHighPriorityTasks() {
    for (final task in _tasks.where((t) => t.priority == TaskPriority.high)) {
      task.resume();
    }
  }
  
  void _resumeAllTasks() {
    for (final task in _tasks) {
      task.resume();
    }
  }
}

enum TaskPriority {
  high,
  medium,
  low,
}

abstract class BatteryAwareTask {
  final String id;
  final TaskPriority priority;
  bool _isPaused = false;
  
  BatteryAwareTask({required this.id, required this.priority});
  
  bool shouldExecute(PowerState powerState, bool isCharging) {
    if (_isPaused) return false;
    
    switch (priority) {
      case TaskPriority.high:
        return true;
      case TaskPriority.medium:
        return powerState != PowerState.critical || isCharging;
      case TaskPriority.low:
        return powerState == PowerState.normal || isCharging;
    }
  }
  
  void pause() => _isPaused = true;
  void resume() => _isPaused = false;
  
  Future<void> execute();
}

Network Optimization for Battery Life

Intelligent Request Management

typescript
class BatteryAwareNetworkOptimizer {
  private requestQueue: PriorityQueue<NetworkRequest> = new PriorityQueue();
  private batchingEnabled = false;
  private compressionEnabled = false;
  private cacheAggressiveness = 'normal';
  
  updateOptimizationLevel(batteryLevel: number, isCharging: boolean): void {
    if (batteryLevel < 0.15 && !isCharging) {
      this.enableUltraOptimization();
    } else if (batteryLevel < 0.3) {
      this.enableAggressiveOptimization();
    } else if (batteryLevel < 0.6) {
      this.enableModerateOptimization();
    } else {
      this.enableNormalOperation();
    }
  }
  
  private enableUltraOptimization(): void {
    this.batchingEnabled = true;
    this.compressionEnabled = true;
    this.cacheAggressiveness = 'ultra';
    
    // Delay non-critical requests
    this.setRequestDelay('low', 60000); // 1 minute
    this.setRequestDelay('medium', 30000); // 30 seconds
    
    // Enable request deduplication
    this.enableRequestDeduplication(true);
  }
  
  private enableAggressiveOptimization(): void {
    this.batchingEnabled = true;
    this.compressionEnabled = true;
    this.cacheAggressiveness = 'aggressive';
    
    this.setRequestDelay('low', 30000); // 30 seconds
    this.setRequestDelay('medium', 10000); // 10 seconds
    
    this.enableRequestDeduplication(true);
  }
  
  private enableModerateOptimization(): void {
    this.batchingEnabled = true;
    this.compressionEnabled = false;
    this.cacheAggressiveness = 'moderate';
    
    this.setRequestDelay('low', 10000); // 10 seconds
    this.clearRequestDelay('medium');
    
    this.enableRequestDeduplication(false);
  }
  
  private enableNormalOperation(): void {
    this.batchingEnabled = false;
    this.compressionEnabled = false;
    this.cacheAggressiveness = 'normal';
    
    this.clearAllRequestDelays();
    this.enableRequestDeduplication(false);
  }
  
  async makeRequest(request: NetworkRequest): Promise<any> {
    // Check cache first based on aggressiveness
    const cacheResult = await this.checkCache(request);
    if (cacheResult) {
      return cacheResult;
    }
    
    // Apply request optimizations
    const optimizedRequest = this.optimizeRequest(request);
    
    if (this.batchingEnabled && request.priority !== 'critical') {
      return this.queueForBatch(optimizedRequest);
    }
    
    return this.executeRequest(optimizedRequest);
  }
  
  private optimizeRequest(request: NetworkRequest): NetworkRequest {
    const optimized = { ...request };
    
    // Enable compression if configured
    if (this.compressionEnabled) {
      optimized.headers = {
        ...optimized.headers,
        'Accept-Encoding': 'gzip, deflate, br',
      };
    }
    
    // Reduce image quality for image requests
    if (this.isImageRequest(request)) {
      optimized.params = {
        ...optimized.params,
        quality: this.getImageQuality(),
      };
    }
    
    return optimized;
  }
  
  private getImageQuality(): string {
    switch (this.cacheAggressiveness) {
      case 'ultra': return 'low';
      case 'aggressive': return 'medium';
      case 'moderate': return 'medium';
      default: return 'high';
    }
  }
}

Performance Monitoring and Analytics

Battery Usage Analytics

kotlin
class BatteryUsageAnalytics {
    private val powerProfile = PowerProfile(context)
    private val batteryStatsManager = context.getSystemService(Context.BATTERY_STATS_SERVICE) as BatteryStatsManager
    
    fun trackBatteryUsage(component: String, startTime: Long, endTime: Long) {
        val duration = endTime - startTime
        val powerConsumption = estimatePowerConsumption(component, duration)
        
        // Log to analytics
        Analytics.track("battery_usage", mapOf(
            "component" to component,
            "duration_ms" to duration,
            "estimated_power_mah" to powerConsumption,
            "battery_level_before" to getBatteryLevelAtTime(startTime),
            "battery_level_after" to getBatteryLevelAtTime(endTime)
        ))
    }
    
    private fun estimatePowerConsumption(component: String, durationMs: Long): Double {
        val powerMah = when (component) {
            "cpu" -> powerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE)
            "screen" -> powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_ON)
            "wifi" -> powerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)
            "gps" -> powerProfile.getAveragePower(PowerProfile.POWER_GPS_ON)
            "camera" -> powerProfile.getAveragePower(PowerProfile.POWER_CAMERA)
            else -> 0.0
        }
        
        return powerMah * (durationMs / 3600000.0) // mAh per hour
    }
    
    fun generateBatteryReport(): BatteryReport {
        val stats = batteryStatsManager.getBatteryUsageStats()
        val uidStats = stats.uidBatteryUsageStats
        
        val appUsage = uidStats.find { it.uid == android.os.Process.myUid() }
        
        return BatteryReport(
            totalConsumption = appUsage?.consumedPower ?: 0.0,
            cpuUsage = appUsage?.cpuTimeMs ?: 0,
            backgroundUsage = appUsage?.backgroundTimeMs ?: 0,
            foregroundUsage = appUsage?.foregroundActivityTimeMs ?: 0,
            recommendations = generateRecommendations(appUsage)
        )
    }
    
    private fun generateRecommendations(stats: UidBatteryUsageStats?): List<String> {
        val recommendations = mutableListOf<String>()
        
        stats?.let { usage ->
            if (usage.backgroundTimeMs > usage.foregroundActivityTimeMs * 2) {
                recommendations.add("Reduce background activity")
            }
            
            if (usage.consumedPower > 100) { // mAh
                recommendations.add("Optimize power-intensive operations")
            }
        }
        
        return recommendations
    }
}

data class BatteryReport(
    val totalConsumption: Double,
    val cpuUsage: Long,
    val backgroundUsage: Long,
    val foregroundUsage: Long,
    val recommendations: List<String>
)

Best Practices and Guidelines

1. Battery State Awareness

  • Monitor battery level, charging state, and power save mode
  • Adapt app behavior based on current battery conditions
  • Implement graceful degradation for low battery scenarios

2. Background Task Optimization

  • Use platform-appropriate background task mechanisms
  • Implement intelligent task scheduling based on battery state
  • Coalesce and batch background operations

3. Network Efficiency

  • Implement request coalescing and batching
  • Use compression and optimize payload sizes
  • Cache aggressively during low battery conditions

4. Resource Management

  • Monitor and limit CPU-intensive operations
  • Reduce screen brightness and frame rates when needed
  • Disable non-essential features during power save mode

5. User Experience

  • Provide clear indicators of battery optimization modes
  • Allow users to control optimization levels
  • Maintain core functionality even in extreme power save scenarios

Conclusion

Effective battery optimization requires a holistic approach that considers all aspects of mobile application behavior. By implementing intelligent power management systems, monitoring battery conditions, and adapting application behavior accordingly, developers can create applications that provide excellent user experience while respecting device battery constraints.

The key to successful battery optimization is proactive monitoring and adaptive behavior that responds to changing power conditions, ensuring applications remain functional and efficient across all battery levels and charging states.

Created by Eren Demir.