Identify wake locks created by other APIs

Several libraries and system APIs can acquire wake locks that are attributable to your app. This can make it difficult to identify a wake lock in your app that might be causing a problem. If you misuse an API, that might result in your app holding a wake lock for too long, even though you aren't calling the wake lock APIs directly.

This document lists some common wake lock names you might see when you use the wake lock debugging tools. You might also see these names in a report from Android vitals. In some cases, the wake lock might have been created by a library or system API. In other cases, there is a reason why the tool is obfuscating the wake lock name you use in the app. You can use the debugging tools to identify misbehaving wake locks, then search for the wake lock name in this document to identify which API may be causing the problem and how to solve it.

This document covers the scenarios where wake locks might be created. In each case, while the wake lock might be created by some other library or API, the lock is attributed to the app which called that API.

AlarmManager

AlarmManager acquires wake locks and attributes them to the calling app. AlarmManager acquires the wake lock when the alarm goes off, and releases the lock when the alarm broadcast's onReceive() method finishes executing.

Wake lock names

AlarmManager creates wake locks with the name *alarm*. (The asterisks are part of the wake lock name, they do not represent wild cards.)

Recommendation

We recommend the following practices to optimize alarm behavior:

  • Use AlarmManager to optimize alarm scheduling frequency.
  • Only use RTC_WAKEUP alarms (which wake up the device) when necessary.
  • Minimize the use of alarms, and avoid doing lengthy work in the onReceive() method.

Audio and media

Media APIs can acquire wake locks when recording or playing audio. The wake locks are attributed to the calling app.

Wake lock names

Media APIs acquire wake locks with various names that begin with Audio:

  • AudioBitPerfect: Used for lossless USB audio playback.
  • AudioDirectOut: Used for lossless audio playback on a TV or special device.
  • AudioDup: Used for playback of notifications while connected via BlueTooth or USB.
  • AudioIn: Used for audio capture when in camcorder mode while the microphone is active.
  • AudioMix: Used for audio playback to a common device.
  • AudioOffload: Used for long-term music-only playback, for apps that support this mode.
  • AudioSpatial: Used for playback of multi-channel movie or music audio on devices that support spatial audio.
  • AudioUnknown: Used when the other situations do not apply.
  • MmapCapture: Used for low-latency audio capture.
  • MmapPlayback: Used for low-latency playback, such as for gaming or for professional audio applications.

Recommendation

We recommend the following practices:

  • Don't use wake lock names that begin with Audio.
  • If you're using the media APIs, you shouldn't need to acquire wake locks directly; you can rely on the APIs to acquire the necessary wake locks for you.
  • When you use media APIs, end the media session when you no longer need it.

Firebase Cloud Message (FCM)

GCM acquires a wake lock while delivering a Firebase Cloud Message (FCM) broadcast to the app. The wake lock is released once the FCM broadcast onMessageReceived() method finishes executing.

Wake lock names

GCM acquires a wake lock with the name GOOGLE_C2DM.

Recommendation

We recommend the following practices to optimize FCM behavior:

  • Optimize the frequency of FCM delivery.
  • Don't use high-priority FCM unless the message actually needs to be delivered immediately.
  • Have the onMessageReceived() method complete as quickly as possible. See the firebase guidance for more information.

JobScheduler

JobScheduler jobs acquire wake locks while executing tasks in the background. The wake locks are attributed to the app that created the workers.

Wake lock names

The wake lock names acquired by JobScheduler depend on what version of the Android system they're running on, and the purpose of the job.

The items surrounded by angle brackets are variables. For example, "<package_name>" is the name of your app's package, not the literal text <package name>. However, *job* is the character sequence *job*, with asterisks; the asterisks are not being used as wild cards.

Android 15 and lower

User initiated jobs create wake locks with names following this pattern:

*job*u/@<name_space>@/<package_name>/<classname>

Other jobs use this pattern:

*job*/@<name_space>@/<package_name>/<classname>
Android 16 and higher

User-initiated jobs create wake locks with names following this pattern:

*job*u/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

Expedited jobs use this pattern:

*job*e/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

Regular jobs use this pattern:

*job*r/@<name_space>@/#<trace_tag>#/<package_name>/<classname>
Example

Suppose there's an expedited job with the namespace backup and the trace tag started. The package name is com.example.app, and the class that created the job is com.backup.BackupFileService.

On devices running Android 15 or lower, the wake lock would be named:

*job*/@backup@/com.example.app/com.backup.BackupFileService

On devices running Android 16 or higher, the wake lock would be named:

*job*e/@backup@/#started#/com.example.app/com.backup.BackupFileService

Recommendation

Audit your usage of JobScheduler tasks. In particular, follow our guidance for optimizing battery use for task scheduling APIs.

Location

LocationManager and FusedLocationProviderClient use wake locks to acquire and deliver the device location. The wake locks are attributed to the app that called those APIs.

Wake lock names

Location services use the following names:

  • CollectionLib-SigCollector
  • NetworkLocationLocator
  • NetworkLocationScanner
  • NlpCollectorWakeLock
  • NlpWakeLock
  • *location*

Recommendation

Optimize location use. For example, set timeouts, batch location requests, or use passive location updates.

WorkManager

WorkManager workers acquire wake locks while executing tasks in the background. The wake locks are attributed to the app that created the workers.

Wake lock names

The wake lock names acquired by WorkManager depend on what version of the Android system they're running on.

Android 15 and lower

WorkManager tasks create wake locks with names following this pattern:

*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
Android 16 and higher

Expedited tasks create wake locks with names following this pattern:

*job*e/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

Regular tasks follow this pattern:

*job*r/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

By default, <trace_tag> is the worker name.

Example

Suppose there's an expedited worker named BackupFileWorker. The package name is com.example.app.

On devices running Android 15 or lower, the wake lock would be named:

*job*/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

On devices running Android 16 or higher, the wake lock would be named:

*job*e/#BackupFileWorker#/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

Recommendation

Audit your usage of WorkManager workers. In particular, follow our guidance for optimizing battery use for task scheduling APIs.

_UNKNOWN

If the debugging tools think a wake lock name contains personally identifiable information (PII), they don't display the actual wake lock name. Instead, they label the wake lock as _UNKNOWN. For example, tools might do this if the wake lock name contains an email address.

Recommendation

Follow wake lock naming best practices, and avoid using PII in the wake lock name. If you find a wake lock named _UNKNOWN attributed to your app, try to identify which wake lock that is, and give it a different name.