UNPKG

react-native-nitro-battery

Version:

High-performance battery monitoring for React Native built with Nitro Modules

579 lines (440 loc) β€’ 14.8 kB
# react-native-nitro-battery πŸ”‹ High-performance battery monitoring for React Native built with Nitro Modules. ## Overview This module provides comprehensive battery monitoring functionality for React Native applications. Monitor battery level, charging state, and low power mode with real-time updates and listeners, all built with Nitro Modules for optimal native performance and zero-bridge overhead. ## Features - ⚑ High-performance native implementation using Nitro Modules - πŸ”‹ Real-time battery level monitoring - πŸ”Œ Charging state detection (charging, discharging, full, unknown) - οΏ½ Low power mode detection and notifications - 🎯 Event listeners for battery state changes - πŸ“± Cross-platform support (iOS & Android) - πŸš€ Zero-bridge overhead with direct native calls - πŸ›‘οΈ Memory-safe with automatic cleanup and proper listener management ## Requirements - React Native >= 0.76 - Node >= 18 - `react-native-nitro-modules` must be installed (Nitro runtime) ## Installation ```bash npm install react-native-nitro-battery react-native-nitro-modules # or yarn add react-native-nitro-battery react-native-nitro-modules ``` ## Platform Configuration ### iOS No additional configuration required. The module automatically enables battery monitoring when initialized. ### Android Add battery monitoring permission to your `android/app/src/main/AndroidManifest.xml`: ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Optional: For more detailed battery information --> <uses-permission android:name="android.permission.BATTERY_STATS" /> <application android:name=".MainApplication" android:allowBackup="false" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:exported="true" android:theme="@style/LaunchTheme"> <!-- Your existing activity configuration --> </activity> </application> </manifest> ``` ## Quick Usage ```ts import { NitroBattery, addBatteryStateListener, addLowPowerListener, getLevel, isCharging } from 'react-native-nitro-battery' // Get current battery level (0-100) const batteryLevel = getLevel() console.log(`Battery level: ${batteryLevel}%`) // Check if device is charging const charging = isCharging() console.log(`Is charging: ${charging}`) const subscription = state => { console.log('Battery state changed:', state); }; // Listen to battery state changes addBatteryStateListener(subscription); // Listen to low power mode activation removeBatteryStateListener(subscription); // Don't forget to remove listeners when done // removeBatteryStateListener // removeLowPowerListener ``` ## API Reference ### NitroBattery The main battery monitoring module providing direct access to native functionality. ### Core Functions #### `getLevel(): number` Returns the current battery level as a percentage. - **Returns**: Battery level from 0-100, or -1 if unavailable ```ts const level = getLevel() console.log(`Battery: ${level}%`) ``` #### `isCharging(): boolean` Checks if the device is currently charging. - **Returns**: `true` if charging or full, `false` otherwise ```ts const charging = isCharging() if (charging) { console.log('Device is charging') } ``` #### `getBatteryState(): string` Gets the current battery state. - **Returns**: One of: `'charging'`, `'discharging'`, `'full'`, `'unknown'` ```ts const state = NitroBattery.getBatteryState() console.log(`Battery state: ${state}`) ``` #### `isLowPowerModeEnabled(): boolean` Checks if low power mode is currently enabled. - **Returns**: `true` if low power mode is active ```ts const lowPower = NitroBattery.isLowPowerModeEnabled() if (lowPower) { console.log('Device is in low power mode') } ``` ### Event Listeners #### `addBatteryStateListener(listener: BatteryListener): void` Adds a listener for battery state changes. - **listener**: Callback function that receives the new battery state ```ts const listenerId = addBatteryStateListener((state) => { console.log(`Battery state: ${state}`) }) ``` #### `removeBatteryStateListener(listener: BatteryListener): void` Removes a battery state listener. - **listener**: Callback function that receives the new battery state ```ts removeBatteryStateListener(listenerId) ``` #### `addLowPowerListener(listener: LowPowerListener): void` Adds a listener for low power mode activation. - **listener**: Callback function called when low power mode is enabled ```ts addLowPowerListener(() => { console.log('Low power mode activated!') }) ``` #### `removeLowPowerListener(listener: LowPowerListener): void` Removes a low power mode listener. - **listener**: Callback function called when low power mode is enabled ```ts removeLowPowerListener(listenerId) ``` ### Advanced API #### `NitroBattery.removeAllListeners(): void` Removes all registered listeners. Useful for cleanup. ```ts NitroBattery.removeAllListeners() ``` ## Real-world Examples ### Basic Battery Monitoring ```ts import React, { useEffect, useState } from 'react' import { View, Text, Alert } from 'react-native' import { getLevel, isCharging, addBatteryStateListener, addLowPowerListener, removeBatteryStateListener, removeLowPowerListener } from 'react-native-nitro-battery' const BatteryMonitor = () => { const [batteryLevel, setBatteryLevel] = useState(0) const [charging, setCharging] = useState(false) const [batteryState, setBatteryState] = useState('unknown') useEffect(() => { // Get initial values setBatteryLevel(getLevel()) setCharging(isCharging()) }, []) useEffect(() => { const subscription = state => { console.log('Battery state changed:', state); }; addBatteryStateListener(subscription); return () => { removeBatteryStateListener(subscription); }; }, []); const getBatteryColor = () => { if (charging) return '#4CAF50' // Green when charging if (batteryLevel < 20) return '#F44336' // Red when low if (batteryLevel < 50) return '#FF9800' // Orange when medium return '#4CAF50' // Green when good } const getBatteryIcon = () => { if (charging) return 'πŸ”Œ' if (batteryLevel < 20) return 'πŸͺ«' return 'πŸ”‹' } return ( <View style={{ padding: 20, alignItems: 'center' }}> <Text style={{ fontSize: 48 }}>{getBatteryIcon()}</Text> <Text style={{ fontSize: 32, fontWeight: 'bold', color: getBatteryColor() }}> {batteryLevel}% </Text> <Text style={{ fontSize: 18, marginTop: 10 }}> Status: {charging ? 'Charging' : 'Not Charging'} </Text> <Text style={{ fontSize: 16, marginTop: 5, color: '#666' }}> State: {batteryState} </Text> </View> ) } ``` ### Power Management Hook ```ts import { useState, useEffect, useCallback } from 'react' import { getLevel, isCharging, addBatteryStateListener, addLowPowerListener, removeBatteryStateListener, removeLowPowerListener, NitroBattery } from 'react-native-nitro-battery' export interface BatteryInfo { level: number isCharging: boolean state: string isLowPowerMode: boolean } export const useBattery = () => { const [batteryInfo, setBatteryInfo] = useState<BatteryInfo>({ level: getLevel(), isCharging: isCharging(), state: NitroBattery.getBatteryState(), isLowPowerMode: NitroBattery.isLowPowerModeEnabled(), }) const updateBatteryInfo = useCallback(() => { setBatteryInfo({ level: getLevel(), isCharging: isCharging(), state: NitroBattery.getBatteryState(), isLowPowerMode: NitroBattery.isLowPowerModeEnabled(), }) }, []) useEffect(() => { const batteryListener = addBatteryStateListener((state) => { updateBatteryInfo() }) const lowPowerListener = addLowPowerListener(() => { updateBatteryInfo() }) return () => { removeBatteryStateListener(batteryListener) removeLowPowerListener(lowPowerListener) } }, [updateBatteryInfo]) return { ...batteryInfo, refresh: updateBatteryInfo, isLowBattery: batteryInfo.level < 20, isCriticalBattery: batteryInfo.level < 10, batteryHealth: batteryInfo.level > 80 ? 'excellent' : batteryInfo.level > 50 ? 'good' : batteryInfo.level > 20 ? 'fair' : 'poor' } } // Usage in component const BatteryStatus = () => { const { level, isCharging, state, isLowPowerMode, isLowBattery, isCriticalBattery, batteryHealth } = useBattery() return ( <View> <Text>Battery: {level}%</Text> <Text>Charging: {isCharging ? 'Yes' : 'No'}</Text> <Text>State: {state}</Text> <Text>Low Power Mode: {isLowPowerMode ? 'On' : 'Off'}</Text> <Text>Health: {batteryHealth}</Text> {isLowBattery && <Text style={{color: 'red'}}>⚠️ Low Battery</Text>} {isCriticalBattery && <Text style={{color: 'red'}}>🚨 Critical Battery</Text>} </View> ) } ``` ## Best Practices ### Memory Management Always clean up listeners to prevent memory leaks: ```ts useEffect(() => { const subscription = state => { console.log('Battery state changed:', state); }; addBatteryStateListener(subscription); return () => { removeBatteryStateListener(subscription); }; }, []); ``` ### Performance Considerations - Battery monitoring has minimal performance impact - Listeners are called on the main thread for UI updates - Use throttling for frequent UI updates if needed ```ts // Good: Throttled battery level updates let lastUpdate = 0 const THROTTLE_MS = 1000 // Update UI max once per second addBatteryStateListener((state) => { const now = Date.now() if (now - lastUpdate > THROTTLE_MS) { updateUI(getLevel(), state) lastUpdate = now } }) ``` ### Error Handling ```ts try { const level = getLevel() if (level === -1) { console.warn('Battery level unavailable') // Handle unavailable battery info } else { // Use battery level normally console.log(`Battery: ${level}%`) } } catch (error) { console.error('Battery monitoring error:', error) } ``` ### Battery Optimization Tips Based on battery state, you can optimize your app's behavior: ```ts addBatteryStateListener((state) => { switch (state) { case 'charging': // Device is charging, safe to perform intensive tasks enableHighPerformanceMode() break case 'discharging': // On battery power, optimize for efficiency enablePowerSavingMode() break case 'full': // Battery full, can perform maintenance tasks performMaintenanceTasks() break } }) addLowPowerListener(() => { // User enabled low power mode, reduce app functionality enableMinimalMode() pauseNonEssentialServices() }) ``` ## Platform Support ### Android Implementation Details - βœ… Full battery monitoring support - βœ… Real-time battery state changes - βœ… Low power mode detection (Android 5.0+) - βœ… Battery level accuracy within 1% - βœ… Works with all Android versions ### iOS Implementation Details - βœ… Full battery monitoring support - βœ… Real-time battery state changes - βœ… Low power mode detection (iOS 9.0+) - βœ… Battery level accuracy within 1% - βœ… Automatic battery monitoring management ## Troubleshooting ### Common Issues #### Battery level returns -1 (iOS) - This is normal on iOS Simulator (no battery) - On real devices, ensure battery monitoring is enabled (handled automatically) #### Battery state listeners not firing - Verify listeners are properly added and stored - Check that listeners are removed in cleanup functions - Ensure the app has proper permissions (Android) #### Memory leaks with listeners - Always store listener IDs returned from add functions - Remove listeners in component cleanup/unmount ## Migration Guide ### From other battery libraries ```ts // Before (react-native-battery) import { getBatteryLevel, isCharging } from 'react-native-battery' // After (react-native-nitro-battery) import { getLevel, isCharging } from 'react-native-nitro-battery' // Most APIs are similar or improved const level = getLevel() // Instead of getBatteryLevel() const charging = isCharging() // Same API ``` ### Adding event listeners ```ts // Before (typical pattern with other libraries) import { BatteryManager } from 'some-battery-library' BatteryManager.addEventListener('batteryLevelChange', callback) // After (react-native-nitro-battery) import { addBatteryStateListener, removeBatteryStateListener } from 'react-native-nitro-battery' useEffect(() => { const subscription = state => { console.log('Battery state changed:', state); }; addBatteryStateListener(subscription); return () => { removeBatteryStateListener(subscription); }; }, []); ``` ## Type Definitions ```ts // Listener function types type BatteryListener = (state: string) => void type LowPowerListener = () => void // Main API interface interface NitroBatterySpec { getLevel(): number isCharging(): boolean getBatteryState(): string isLowPowerModeEnabled(): boolean addBatteryStateListener(listener: BatteryListener): string removeBatteryStateListener(listener: BatteryListener): void addLowPowerListener(listener: LowPowerListener): string removeLowPowerListener(listener: LowPowerListener): void } ``` ## Contributing See `CONTRIBUTING.md` for contribution workflow. When updating spec files in `src/specs/*.nitro.ts`, regenerate Nitro artifacts: ```bash yarn nitrogen ``` ## Project Structure - `android/` β€” Native Android implementation (Kotlin/Java) - `ios/` β€” Native iOS implementation (Swift) - `src/` β€” TypeScript source code and exports - `nitrogen/` β€” Generated Nitro artifacts (auto-generated) - `lib/` β€” Compiled JavaScript output ## Acknowledgements Special thanks to the following projects that inspired this library: - [mrousavy/nitro](https://github.com/mrousavy/nitro) – Nitro Modules architecture ## License MIT Β© [ThΓ nh CΓ΄ng](https://github.com/tconns)