In mobile battery management on Android, excessive device wakeups are among the leading causes of passive battery drain. When an application configures wakeup alarms via the AlarmManager API (such as RTC_WAKEUP or ELAPSED_REALTIME_WAKEUP), the Android system instructs the hardware power management IC (PMIC) to bring the CPU out of deep low-power sleep states to process background tasks. To diagnose rogue wakeup loops, optimize alarm batching, and verify AlarmManager quotas across power-saving states, developers can interrogate the system alarm state directly via Android Debug Bridge (ADB).
In this guide, you will learn how to dump pending alarms, audit top wakeup culprits, evaluate batching windows, and test alarm triggers on Android using adb shell dumpsys alarm.
Understanding Android AlarmManager and Wakeup Types
The Android framework provides two primary categories of scheduled alarms:
- Non-Wakeup Alarms (
RTC,ELAPSED_REALTIME): Do not wake up the device when fired. If the screen is off and the CPU is asleep, the system holds the alarm until the next time the device wakes up naturally (e.g., when the user turns on the screen or another process triggers a wakeup). - Wakeup Alarms (
RTC_WAKEUP,ELAPSED_REALTIME_WAKEUP): Hold a partial wake lock, turning on the application processor immediately even if the phone is asleep in a pocket or on a desk.
Since Android 6.0 (Doze mode) and Android 12 (exact alarm permissions via SCHEDULE_EXACT_ALARM), the operating system aggressively batches and throttles alarms. Using ADB, you can observe these internal batching windows in real time.
Dumping AlarmManager State for a Specific Application
Connect your Android phone or emulator via USB or Wi-Fi, and confirm ADB connectivity:
adb devices
To inspect all alarms registered by a target application, invoke dumpsys alarm filtered by your package name:
adb shell dumpsys alarm com.example.myapp
The diagnostic dump provides three crucial sections:
- Alarm Stats: Historical metrics showing how many times the app has fired alarms since the device was booted.
- Pending Alarms: Currently scheduled intents awaiting execution.
- Broadcast Intents: Target
PendingIntentactions and receiver components associated with each trigger.
Analyzing Top Wakeup Culprits and Alarm Frequency
To identify which background components are causing excessive battery drain across the entire operating system, query the global alarm statistics table:
adb shell dumpsys alarm | grep -A 10 "Top Alarm Endpoints:"
Alternatively, inspect the per-package wakeup summary:
adb shell dumpsys alarm | grep -E "com.example.myapp" -A 4 -B 1
Look for the wakeup count metric:
+12m45s running, 142 wakeups: com.example.myapp
*alarm*:com.example.myapp/.services.SyncReceiver: 120 wakeups
*alarm*:com.example.myapp/.telemetry.FlushReceiver: 22 wakeups
If an application wakes the CPU hundreds of times per hour while the screen is off, migrate non-urgent tasks from RTC_WAKEUP to inexact batch alarms or JobScheduler/WorkManager.
Auditing Pending Alarm Batches and Delivery Times
The Android OS groups disparate app alarms into unified time batches to minimize the total number of CPU wakeup cycles. To inspect scheduled batches:
adb shell dumpsys alarm | grep -A 25 "Pending alarm batches:"
Each batch displays the planned start time and end of the delivery window:
Batch{3f2e1a4 numAlarms=4 start=1452200 end=1482200 flgs=0x1}:
RTC_WAKEUP #0: Alarm{89ab12 type 0 origWhen 1452200 ... com.example.myapp}
RTC #1: Alarm{33cd44 type 1 origWhen 1460000 ... com.google.android.gms}
Notice how Android aligns the non-wakeup Google Mobile Services alarm with your app’s wakeup alarm, ensuring both process in a single CPU wake cycle.
Testing Alarm Triggers During Doze and Standby Buckets
When an Android device enters deep Doze mode, standard alarms are deferred to periodic maintenance windows unless scheduled via setExactAndAllowWhileIdle() or setAlarmClock().
To test how your application’s alarms behave during Doze mode:
- Simulate disconnecting the charging cable:
adb shell dumpsys battery unplug - Step into deep Doze mode:
adb shell dumpsys deviceidle force-idle - Inspect the alarm dump to confirm that standard alarms are deferred:
Look for theadb shell dumpsys alarm com.example.myapp[IDLE-UNTIL]flag indicating that triggers are held until the maintenance window opens. - Step the device into the next maintenance window to trigger batch execution:
adb shell dumpsys deviceidle step - Once testing is complete, restore the battery charging status:
adb shell dumpsys deviceidle unforce adb shell dumpsys battery reset
Checking Exact Alarm Permissions and Quotas
Starting with Android 12 (API level 31) and Android 13, apps targeting modern SDKs must hold the SCHEDULE_EXACT_ALARM or USE_EXACT_ALARM permission to trigger alarms at precise millisecond boundaries. If the user revokes this permission in system settings, exact alarms revert to inexact delivery.
To verify whether your application holds exact alarm privileges:
adb shell cmd appops get com.example.myapp SCHEDULE_EXACT_ALARM
If the result displays SCHEDULE_EXACT_ALARM: allow, the application can schedule precise wakeups. If it shows deny, test your app’s graceful fallback logic to ensure inexact batching operates without application crashes.