Testing Doze mode
Android’s Doze mode is triggered when the device is unplugged, stationary, and the screen is off for an extended period. You can force your device into Doze mode using ADB commands to test how your app behaves.
Prerequisites
- Android device or emulator connected via ADB
- USB debugging enabled on device
- ADB installed on your development machine
Force device into Doze mode
-
Disconnect device from charger (required for Doze mode)
-
Connect via ADB
-
Unplug USB charging (if testing on physical device)
adb shell dumpsys battery unplug
-
Force device into idle state
adb shell dumpsys deviceidle force-idle
-
Verify Doze mode is active
const isIdle = await BackgroundGuardian.isDeviceIdleMode();
console.log('Device in Doze mode:', isIdle);
Exit Doze mode
To return the device to normal operation:
# Exit idle mode
adb shell dumpsys deviceidle unforce
# Reset battery status
adb shell dumpsys battery reset
Always reset battery status after testing. Otherwise, your device may continue to report it’s unplugged even when connected to power.
Step through Doze mode states
To gradually simulate the Doze mode progression:
# Move to next idle state
adb shell dumpsys deviceidle step
# Repeat multiple times to reach deep idle
adb shell dumpsys deviceidle step
adb shell dumpsys deviceidle step
Debugging wake locks
Check if wake lock is held
Use ADB to inspect all active wake locks on the device:
adb shell dumpsys power | grep "BackgroundGuardian"
This shows:
- Whether your wake lock is active
- How long it has been held
- The wake lock tag (if you specified one)
Example output
Wake Locks: size=2
PARTIAL_WAKE_LOCK 'BackgroundGuardian' (uid=10123, pid=12345, ws=WorkSource{10123})
tag="AudioPlayer"
flags=0x1
activated=true
Check wake lock programmatically
Add debug logging to your app:
import BackgroundGuardian from "react-native-background-guardian";
async function debugWakeLock() {
const isHeld = await BackgroundGuardian.isWakeLockHeld();
console.log('Wake lock held:', isHeld);
if (!isHeld) {
console.warn('Wake lock was released unexpectedly!');
}
}
// Check periodically
setInterval(debugWakeLock, 10000); // Every 10 seconds
View all system wake locks
To see all wake locks from all apps:
Look for the “Wake Locks” section in the output.
Checking battery optimization status
Via ADB
Check if your app is whitelisted from battery optimizations:
adb shell dumpsys deviceidle whitelist
Look for your app’s package name in the output.
Via app code
Add logging to verify exemption status:
import BackgroundGuardian from "react-native-background-guardian";
import { AppState } from "react-native";
function useBatteryOptimizationDebug() {
useEffect(() => {
async function checkStatus() {
const isIgnoring = await BackgroundGuardian.isIgnoringBatteryOptimizations();
const isPowerSave = await BackgroundGuardian.isPowerSaveMode();
const isIdle = await BackgroundGuardian.isDeviceIdleMode();
console.log('Battery Optimization Status:', {
isIgnoringOptimizations: isIgnoring,
isPowerSaveMode: isPowerSave,
isDeviceIdle: isIdle,
});
}
checkStatus();
// Re-check when app returns to foreground
const subscription = AppState.addEventListener('change', (state) => {
if (state === 'active') {
checkStatus();
}
});
return () => subscription.remove();
}, []);
}
Testing OEM-specific settings
Check device manufacturer
const manufacturer = await BackgroundGuardian.getDeviceManufacturer();
console.log('Device manufacturer:', manufacturer);
// Test OEM settings availability
const opened = await BackgroundGuardian.openOEMSettings();
console.log('OEM settings opened:', opened);
Manual testing checklist
For devices with aggressive battery optimization:
Verify that:
openOEMSettings() opens the correct settings page
- The settings page allows whitelisting your app
- Background functionality works after whitelisting
Common debugging scenarios
Scenario 1: Wake lock released unexpectedly
Symptoms: Background task stops running even though wake lock was acquired.
Debug steps:
# Check if wake lock is still held
adb shell dumpsys power | grep "BackgroundGuardian"
# Check battery optimization status
adb shell dumpsys deviceidle whitelist | grep com.yourapp
# Check if device is in Doze mode
adb shell dumpsys deviceidle get deep
Common causes:
- Wake lock timeout expired (default 24 hours)
- App was force-stopped by user
- OEM battery optimization killed the app
Scenario 2: Battery exemption not working
Symptoms: App still killed in background despite exemption.
Debug steps:
// Verify exemption status
const isIgnoring = await BackgroundGuardian.isIgnoringBatteryOptimizations();
console.log('Exemption granted:', isIgnoring);
// Check Power Save mode (affects even exempt apps)
const isPowerSave = await BackgroundGuardian.isPowerSaveMode();
console.log('Power Save mode:', isPowerSave);
// Check OEM manufacturer
const manufacturer = await BackgroundGuardian.getDeviceManufacturer();
console.log('Manufacturer:', manufacturer);
Common causes:
- Power Save mode is enabled (affects all apps)
- OEM-specific battery optimization not disabled
- App Standby restrictions
Scenario 3: Screen wake lock not working
Symptoms: Screen turns off despite calling enableScreenWakeLock().
Debug steps:
// Verify screen wake lock is enabled
const enabled = await BackgroundGuardian.enableScreenWakeLock();
console.log('Screen wake lock enabled:', enabled);
// Try re-enabling after navigation
navigation.addListener('focus', async () => {
await BackgroundGuardian.enableScreenWakeLock();
});
Common causes:
- Screen wake lock only works when app is in foreground
- Flag cleared when navigating between screens
- Another component disabled the flag
Track wake lock duration
let wakeLockStartTime: number | null = null;
async function acquireWakeLockWithTracking(tag: string) {
wakeLockStartTime = Date.now();
const acquired = await BackgroundGuardian.acquireWakeLock(tag);
if (acquired) {
console.log(`[${tag}] Wake lock acquired at ${new Date().toISOString()}`);
}
return acquired;
}
async function releaseWakeLockWithTracking() {
const released = await BackgroundGuardian.releaseWakeLock();
if (released && wakeLockStartTime) {
const duration = Date.now() - wakeLockStartTime;
console.log(`Wake lock held for ${duration}ms (${(duration / 1000 / 60).toFixed(1)} minutes)`);
wakeLockStartTime = null;
}
return released;
}
Monitor battery impact
# Check battery stats for your app
adb shell dumpsys batterystats --charged com.yourapp
# Reset battery stats
adb shell dumpsys batterystats --reset
Wake locks can significantly impact battery life. Always release them when background work is complete.
Testing checklist
Before releasing your app, verify: