public abstract class

WakefulBroadcastReceiver

extends BroadcastReceiver

 java.lang.Object

↳BroadcastReceiver

↳androidx.legacy.content.WakefulBroadcastReceiver

Gradle dependencies

compile group: 'androidx.legacy', name: 'legacy-support-core-utils', version: '1.0.0'

  • groupId: androidx.legacy
  • artifactId: legacy-support-core-utils
  • version: 1.0.0

Artifact androidx.legacy:legacy-support-core-utils:1.0.0 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.legacy:legacy-support-core-utils com.android.support:support-core-utils

Androidx class mapping:

androidx.legacy.content.WakefulBroadcastReceiver android.support.v4.content.WakefulBroadcastReceiver

Overview

This helper is for an old pattern of implementing a BroadcastReceiver that receives a device wakeup event and then passes the work off to a , while ensuring that the device does not go back to sleep during the transition.

This class takes care of creating and managing a partial wake lock for you; you must request the permission to use it.

Wakelocks held by this class are reported to tools as "androidx.core:wake:".

Example

A WakefulBroadcastReceiver uses the method startWakefulService() to start the service that does the work. This method is comparable to , except that the WakefulBroadcastReceiver is holding a wake lock when the service starts. The intent that is passed with startWakefulService() holds an extra identifying the wake lock.

frameworks/support/samples/Support4Demos/src/main/java/com/example/android/supportv4/content/SimpleWakefulReceiver.java complete

The service (in this example, an ) does some work. When it is finished, it releases the wake lock by calling completeWakefulIntent(intent). The intent it passes as a parameter is the same intent that the WakefulBroadcastReceiver originally passed in.

frameworks/support/samples/Support4Demos/src/main/java/com/example/android/supportv4/content/SimpleWakefulService.java complete

Summary

Constructors
publicWakefulBroadcastReceiver()

Methods
public static booleancompleteWakefulIntent(Intent intent)

Finish the execution from a previous WakefulBroadcastReceiver.startWakefulService(Context, Intent).

public static ComponentNamestartWakefulService(Context context, Intent intent)

Do a , but holding a wake lock while the service starts.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public WakefulBroadcastReceiver()

Methods

public static ComponentName startWakefulService(Context context, Intent intent)

Do a , but holding a wake lock while the service starts. This will modify the Intent to hold an extra identifying the wake lock; when the service receives it in , it should pass back the Intent it receives there to WakefulBroadcastReceiver in order to release the wake lock.

Parameters:

context: The Context in which it operate.
intent: The Intent with which to start the service, as per .

public static boolean completeWakefulIntent(Intent intent)

Finish the execution from a previous WakefulBroadcastReceiver.startWakefulService(Context, Intent). Any wake lock that was being held will now be released.

Parameters:

intent: The Intent as originally generated by WakefulBroadcastReceiver.startWakefulService(Context, Intent).

Returns:

Returns true if the intent is associated with a wake lock that is now released; returns false if there was no wake lock specified for it.

Source

/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.legacy.content;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.util.Log;
import android.util.SparseArray;

/**
 * This helper is for an old pattern of implementing a {@link BroadcastReceiver}
 * that receives a device wakeup event and then passes the work off
 * to a {@link android.app.Service}, while ensuring that the
 * device does not go back to sleep during the transition.
 *
 * <p>This class takes care of creating and managing a partial wake lock
 * for you; you must request the {@link android.Manifest.permission#WAKE_LOCK}
 * permission to use it.</p>
 *
 * <p>Wakelocks held by this class are reported to tools as
 * {@code "androidx.core:wake:<component-name>"}.</p>
 *
 * <h3>Example</h3>
 *
 * <p>A {@link WakefulBroadcastReceiver} uses the method
 * {@link WakefulBroadcastReceiver#startWakefulService startWakefulService()}
 * to start the service that does the work. This method is comparable to
 * {@link android.content.Context#startService startService()}, except that
 * the {@link WakefulBroadcastReceiver} is holding a wake lock when the service
 * starts. The intent that is passed with
 * {@link WakefulBroadcastReceiver#startWakefulService startWakefulService()}
 * holds an extra identifying the wake lock.</p>
 *
 * {@sample frameworks/support/samples/Support4Demos/src/main/java/com/example/android/supportv4/content/SimpleWakefulReceiver.java
 *      complete}
 *
 * <p>The service (in this example, an {@link android.app.IntentService}) does
 * some work. When it is finished, it releases the wake lock by calling
 * {@link WakefulBroadcastReceiver#completeWakefulIntent
 * completeWakefulIntent(intent)}. The intent it passes as a parameter
 * is the same intent that the {@link WakefulBroadcastReceiver} originally
 * passed in.</p>
 *
 * {@sample frameworks/support/samples/Support4Demos/src/main/java/com/example/android/supportv4/content/SimpleWakefulService.java
 *      complete}
 *
 * @deprecated As of {@link android.os.Build.VERSION_CODES#O Android O}, background check
 * restrictions make this class no longer generally useful.  (It is generally not safe to
 * start a service from the receipt of a broadcast, because you don't have any guarantees
 * that your app is in the foreground at this point and thus allowed to do so.)  Instead,
 * developers should use android.app.job.JobScheduler to schedule a job, and this
 * does not require that the app hold a wake lock while doing so (the system will take
 * care of holding a wake lock for the job).
 */
@Deprecated
public abstract class WakefulBroadcastReceiver extends BroadcastReceiver {
    private static final String EXTRA_WAKE_LOCK_ID = "androidx.contentpager.content.wakelockid";

    private static final SparseArray<PowerManager.WakeLock> sActiveWakeLocks = new SparseArray<>();
    private static int mNextId = 1;

    /**
     * Do a {@link android.content.Context#startService(android.content.Intent)
     * Context.startService}, but holding a wake lock while the service starts.
     * This will modify the Intent to hold an extra identifying the wake lock;
     * when the service receives it in {@link android.app.Service#onStartCommand
     * Service.onStartCommand}, it should pass back the Intent it receives there to
     * {@link #completeWakefulIntent(android.content.Intent)} in order to release
     * the wake lock.
     *
     * @param context The Context in which it operate.
     * @param intent The Intent with which to start the service, as per
     * {@link android.content.Context#startService(android.content.Intent)
     * Context.startService}.
     */
    public static ComponentName startWakefulService(Context context, Intent intent) {
        synchronized (sActiveWakeLocks) {
            int id = mNextId;
            mNextId++;
            if (mNextId <= 0) {
                mNextId = 1;
            }

            intent.putExtra(EXTRA_WAKE_LOCK_ID, id);
            ComponentName comp = context.startService(intent);
            if (comp == null) {
                return null;
            }

            PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    "androidx.core:wake:" + comp.flattenToShortString());
            wl.setReferenceCounted(false);
            wl.acquire(60 * 1000);
            sActiveWakeLocks.put(id, wl);
            return comp;
        }
    }

    /**
     * Finish the execution from a previous {@link #startWakefulService}.  Any wake lock
     * that was being held will now be released.
     *
     * @param intent The Intent as originally generated by {@link #startWakefulService}.
     * @return Returns true if the intent is associated with a wake lock that is
     * now released; returns false if there was no wake lock specified for it.
     */
    public static boolean completeWakefulIntent(Intent intent) {
        final int id = intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0);
        if (id == 0) {
            return false;
        }
        synchronized (sActiveWakeLocks) {
            PowerManager.WakeLock wl = sActiveWakeLocks.get(id);
            if (wl != null) {
                wl.release();
                sActiveWakeLocks.remove(id);
                return true;
            }
            // We return true whether or not we actually found the wake lock
            // the return code is defined to indicate whether the Intent contained
            // an identifier for a wake lock that it was supposed to match.
            // We just log a warning here if there is no wake lock found, which could
            // happen for example if this function is called twice on the same
            // intent or the process is killed and restarted before processing the intent.
            Log.w("WakefulBroadcastReceiv.", "No active wake lock id #" + id);
            return true;
        }
    }
}