summaryrefslogtreecommitdiffstats
path: root/docs/html/training
diff options
context:
space:
mode:
authorKatie McCormick <kmccormick@google.com>2013-09-05 14:46:20 -0700
committerKatie McCormick <kmccormick@google.com>2013-09-23 10:02:20 -0700
commit7bdb3f6997c5235777d08c0f5a12dfb41551c960 (patch)
tree08afffc6263946072e2824d3992fb21e4f07479c /docs/html/training
parent1e6c936e84675925ef5c58a04c6e80d8894d7128 (diff)
downloadframeworks_base-7bdb3f6997c5235777d08c0f5a12dfb41551c960.zip
frameworks_base-7bdb3f6997c5235777d08c0f5a12dfb41551c960.tar.gz
frameworks_base-7bdb3f6997c5235777d08c0f5a12dfb41551c960.tar.bz2
New Scheduling class.
Change-Id: Iadd9d0d1d3bb8fa6a145d68ee28ae9912a6a9f4c
Diffstat (limited to 'docs/html/training')
-rw-r--r--docs/html/training/best-background.jd8
-rw-r--r--docs/html/training/scheduling/alarms.jd312
-rw-r--r--docs/html/training/scheduling/index.jd66
-rw-r--r--docs/html/training/scheduling/wakelock.jd215
-rw-r--r--docs/html/training/training_toc.cs104
5 files changed, 667 insertions, 38 deletions
diff --git a/docs/html/training/best-background.jd b/docs/html/training/best-background.jd
new file mode 100644
index 0000000..917eabb
--- /dev/null
+++ b/docs/html/training/best-background.jd
@@ -0,0 +1,8 @@
+page.title=Best Practices for Background Jobs
+page.trainingcourse=true
+
+@jd:body
+
+
+<p>These classes show you how to run jobs in the background to boost your
+application's performance and minimize its drain on the battery.</p>
diff --git a/docs/html/training/scheduling/alarms.jd b/docs/html/training/scheduling/alarms.jd
new file mode 100644
index 0000000..758dc95
--- /dev/null
+++ b/docs/html/training/scheduling/alarms.jd
@@ -0,0 +1,312 @@
+page.title=Scheduling Repeating Alarms
+parent.title=Using Wake Locks
+parent.link=index.html
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#set">Set a Repeating Alarm</a></li>
+ <li><a href="#cancel">Cancel an Alarm</a></li>
+ <li><a href="#boot">Start an Alarm When the Device Boots</a></li>
+</ol>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/Scheduler.zip"
+class="button">Download the sample</a>
+ <p class="filename">Scheduler.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Alarms (based on the {@link android.app.AlarmManager} class) give you a way to perform
+time-based operations outside the lifetime of your application.
+For example, you could use an alarm to initiate a long-running operation, such
+as starting a service once a day to download a weather forecast.</p>
+
+<p>Alarms have these characteristics:</p>
+<ul>
+
+<li>They let you fire Intents at set times and/or intervals.</li>
+
+<li>You can use them in conjunction with broadcast receivers to start services and perform
+other operations.</li>
+
+<li>They operate outside of your application, so you can use them to trigger events or
+actions even when your app is not running, and even if the device itself is asleep.</li>
+
+<li>They help you to minimize your app's resource requirements. You can schedule operations
+without relying on timers or continuously running background services.</li>
+
+</ul>
+
+<p class="note"><strong>Note:</strong> For timing operations that are guaranteed to occur
+<em>during</em> the lifetime of your application,
+instead consider using the {@link android.os.Handler} class in conjunction with
+{@link java.util.Timer} and {@link java.lang.Thread}. This approach gives Android better
+control over system resources.</p>
+
+<h2 id="set">Set a Repeating Alarm</h2>
+
+<p>As described above, repeating alarms are a good choice for scheduling regular events or
+data lookups. A repeating alarm has the following characteristics:</p>
+
+<ul>
+<li>A alarm type. For more discussion, see <a href="#type">Choose an alarm type</a>.</li>
+<li>A trigger time. If the trigger time you specify is in the past, the alarm triggers
+immediately.</li>
+<li>The alarm's interval. For example, once a day, every hour, every 5 seconds, and so on.</li>
+<li>A pending intent that fires when the alarm is triggered. When you set a second alarm
+that uses the same pending intent, it replaces the original alarm.</li>
+</ul>
+
+<p>Every choice you make in designing your repeating alarm can have consequences in how your
+app uses (or abuses) system resources. Even a carefully managed alarm can have a major impact
+on battery life. Follow these guidelines as you design your app:</p>
+
+<ul>
+<li>Keep your alarm frequency to a minimum.</li>
+<li>Don't wake up the device unnecessarily (this behavior is determined by the alarm type,
+as described in <a href="#type">Choose an alarm type</a>).</li>
+<li>Don't make your alarm's trigger time any more precise than it has to be:
+
+<ul>
+<li>Use {@link android.app.AlarmManager#setInexactRepeating setInexactRepeating()} instead
+of {@link android.app.AlarmManager#setRepeating setRepeating()} whenever possible.
+When you use {@link android.app.AlarmManager#setInexactRepeating setInexactRepeating()},
+Android synchronizes multiple inexact repeating alarms and fires
+them at the same time. This reduces the drain on the battery.</li>
+<li>If your alarm's behavior is based on an interval (for example, your alarm
+fires once an hour) rather than a precise trigger time (for example, your alarm fires at
+7 a.m. sharp and every 20 minutes after that), use an {@code ELAPSED_REALTIME}
+alarm type.</li>
+</ul></li>
+
+</ul>
+
+<h3 id="type">Choose an alarm type</h3>
+
+<p>One of the first considerations in using a repeating alarm is what its type should be.</p>
+
+
+<p>There are two general clock types for alarms: "elapsed real time" and "real time clock"
+(RTC).
+Elapsed real time uses the "time since system boot" as a
+reference, and real time clock uses UTC (wall clock) time. This means that
+elapsed real time is suited to setting an alarm based on the passage of time (for
+example, an alarm that fires every 30 seconds) since it isn't affected by
+time zone/locale. The real time clock type is better suited for alarms that are dependent
+on current locale.</p>
+
+<p>Both types have a "wakeup" version, which says to wake up the device's CPU if the
+screen is off. This ensures that the alarm will fire at the scheduled time. This is useful
+if your app has a time dependency&mdash;for example, if it has a limited window to perform a
+particular operation. If you don't use the wakeup version of your alarm type, then
+all the repeating alarms will fire when your device is next awake.</p>
+
+<p>If you simply need your alarm to fire at a particular interval (for example, every half
+hour), use one of the elapsed real time types. In general, this is the better choice.</p>
+
+<p>If you need your alarm to fire at a particular time of day,
+then choose one of the clock-based real time clock types. Note, however, that this approach can
+have some drawbacks&mdash;the app may not translate well to other locales, and if the user
+changes the device's time setting, it could cause unexpected behavior in your app.</p>
+
+<p>Here is the list of types:</p>
+
+<ul>
+
+<li>{@link android.app.AlarmManager#ELAPSED_REALTIME}&mdash;Fires the pending intent based
+on the amount of time since the device was booted, but doesn't wake up the device. The
+elapsed time includes any time during which the device was asleep.</li>
+
+<li>{@link android.app.AlarmManager#ELAPSED_REALTIME_WAKEUP}&mdash;Wakes up the device and
+fires the pending intent after the specified length of time has elapsed since device
+boot.</li>
+
+<li>{@link android.app.AlarmManager#RTC}&mdash;Fires the pending intent
+at the specified time but does not wake up the device.</li>
+
+<li>{@link android.app.AlarmManager#RTC_WAKEUP}&mdash;Wakes up the
+device to fire the pending intent at the specified time.</li>
+</ul>
+
+<h4>ELAPSED_REALTIME_WAKEUP examples</h3>
+
+<p>Here are some examples of using {@link android.app.AlarmManager#ELAPSED_REALTIME_WAKEUP}.
+</p>
+
+<p>Wake up the device to fire the alarm in 30 minutes, and every 30 minutes
+after that:</p>
+
+<pre>
+// Hopefully your alarm will have a lower frequency than this!
+alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ AlarmManager.INTERVAL_HALF_HOUR,
+ AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);</pre>
+
+<p>Wake up the device to fire a one-time (non-repeating) alarm in one minute:</p>
+
+<pre>private AlarmManager alarmMgr;
+private PendingIntent alarmIntent;
+...
+alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
+Intent intent = new Intent(context, AlarmReceiver.class);
+alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
+
+alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ SystemClock.elapsedRealtime() +
+ 60 * 1000, alarmIntent);</pre>
+
+
+<h4>RTC examples</h3>
+
+<p>Here are some examples of using {@link android.app.AlarmManager#RTC_WAKEUP}.</p>
+
+<p>Wake up the device to fire the alarm at approximately 2:00 p.m., and repeat once a day
+at the same time:</p>
+
+<pre>// Set the alarm to start at approximately 2:00 p.m.
+Calendar calendar = Calendar.getInstance();
+calendar.setTimeInMillis(System.currentTimeMillis());
+calendar.set(Calendar.HOUR_OF_DAY, 14);
+
+// With setInexactRepeating(), you have to use one of the AlarmManager interval
+// constants--in this case, AlarmManager.INTERVAL_DAY.
+alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
+ AlarmManager.INTERVAL_DAY, alarmIntent);</pre>
+
+<p>Wake up the device to fire the alarm at precisely 8:30 a.m., and every 20 minutes
+thereafter:</p>
+
+<pre>private AlarmManager alarmMgr;
+private PendingIntent alarmIntent;
+...
+alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
+Intent intent = new Intent(context, AlarmReceiver.class);
+alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
+
+// Set the alarm to start at 8:30 a.m.
+Calendar calendar = Calendar.getInstance();
+calendar.setTimeInMillis(System.currentTimeMillis());
+calendar.set(Calendar.HOUR_OF_DAY, 8);
+calendar.set(Calendar.MINUTE, 30);
+
+// setRepeating() lets you specify a precise custom interval--in this case,
+// 20 minutes.
+alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
+ 1000 * 60 * 20, alarmIntent);</pre>
+
+<h3>Decide how precise your alarm needs to be</h3>
+
+<p>As described above, choosing the alarm type is often the first step in creating an alarm.
+A further distinction is how precise you need your alarm to be. For most apps,
+{@link android.app.AlarmManager#setInexactRepeating setInexactRepeating()} is the right
+choice.
+When you use this method, Android synchronizes multiple inexact repeating alarms and fires
+them at the same time. This reduces the drain on the battery.</p>
+
+<p>For the rare app that has rigid time requirements&mdash;for example, the alarm needs to
+fire precisely at 8:30 a.m., and every hour on the hour
+thereafter&mdash;use {@link android.app.AlarmManager#setRepeating setRepeating()}. But you
+should avoid using exact alarms if possible.</p>
+
+<p>With {@link android.app.AlarmManager#setInexactRepeating setInexactRepeating()},
+you can't specify a custom interval the way you can with
+{@link android.app.AlarmManager#setRepeating setRepeating()}. You have to use one of the
+interval constants, such as {@link android.app.AlarmManager#INTERVAL_FIFTEEN_MINUTES},
+{@link android.app.AlarmManager#INTERVAL_DAY}, and so on. See {@link android.app.AlarmManager}
+for the complete list.
+</p>
+
+<h2 id="cancel">Cancel an Alarm</h2>
+
+<p>Depending on your app, you may want to include the ability to cancel the alarm.
+To cancel an alarm, call {@link android.app.AlarmManager#cancel cancel()} on the Alarm
+Manager, passing in the {@link android.app.PendingIntent} you no longer want to fire. For
+example:</p>
+
+<pre>// If the alarm has been set, cancel it.
+if (alarmMgr!= null) {
+ alarmMgr.cancel(alarmIntent);
+}</pre>
+
+<h2 id="boot">Start an Alarm When the Device Boots</h2>
+
+<p>By default, all alarms are canceled when a device shuts down.
+To prevent this from happening, you can design your application
+to automatically restart a repeating alarm if the user reboots the device. This ensures
+that the {@link android.app.AlarmManager} will continue doing its task without the user
+needing to manually restart the alarm.</p>
+
+
+<p>Here are the steps:</p>
+<ol>
+<li>Set the <a href="{@docRoot}reference/android/Manifest.permission.html#RECEIVE_BOOT_COMPLETED">
+{@code RECEIVE_BOOT_COMPLETED}</a> permission in your application's manifest. This allows
+your app to receive the
+{@link android.content.Intent#ACTION_BOOT_COMPLETED} that is broadcast after the system
+finishes booting (this only works if the app has already been launched by the user at least once):
+<pre>
+&lt;uses-permission android:name=&quot;android.permission.RECEIVE_BOOT_COMPLETED&quot;/&gt;</pre>
+</li>
+
+<li>Implement a {@link android.content.BroadcastReceiver} to receive the broadcast:
+<pre>public class SampleBootReceiver extends BroadcastReceiver {
+
+ &#64;Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(&quot;android.intent.action.BOOT_COMPLETED&quot;)) {
+ // Set the alarm here.
+ }
+ }
+}</pre></li>
+
+<li>Add the receiver to your app's manifest file with an intent filter that filters on
+the {@link android.content.Intent#ACTION_BOOT_COMPLETED} action:
+
+<pre>&lt;receiver android:name=&quot;.SampleBootReceiver&quot;
+ android:enabled=&quot;false&quot;&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot;&gt;&lt;/action&gt;
+ &lt;/intent-filter&gt;
+&lt;/receiver&gt;</pre>
+
+
+<p>Notice that in the manifest, the boot receiver is set to
+{@code android:enabled=&quot;false&quot;}. This means that the receiver will not be called
+unless the application explicitly enables it. This prevents the boot receiver from being
+called unnecessarily. You can enable a receiver (for example, if the user sets an alarm)
+as follows:</p>
+
+<pre>ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
+PackageManager pm = context.getPackageManager();
+
+pm.setComponentEnabledSetting(receiver,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
+</pre>
+
+<p>Once you enable the receiver this way, it will stay enabled, even if the user reboots
+the device. In other words, programmatically enabling the receiver overrides the
+manifest setting, even across reboots. The receiver will stay enabled until your app disables it.
+You can disable a receiver (for example, if the user cancels an alarm) as follows:</p>
+
+<pre>ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
+PackageManager pm = context.getPackageManager();
+
+pm.setComponentEnabledSetting(receiver,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);</pre>
+
+</li>
+</ol>
diff --git a/docs/html/training/scheduling/index.jd b/docs/html/training/scheduling/index.jd
new file mode 100644
index 0000000..9ffbc16
--- /dev/null
+++ b/docs/html/training/scheduling/index.jd
@@ -0,0 +1,66 @@
+page.title=Managing Device Awake State
+page.tags=""
+
+trainingnavtop=true
+startpage=true
+
+
+@jd:body
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
+<h2>Dependencies and prerequisites</h2>
+
+<ul>
+ <li>Android 1.6 (API Level 4) or higher</li>
+</ul>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/Scheduler.zip"
+class="button">Download the sample</a>
+ <p class="filename">Scheduler.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>
+When an Android device is left idle, it will first dim, then turn off the screen, and
+ultimately turn off the CPU. This prevents the device's battery from quickly getting
+drained. Yet there are times when your application might require a different behavior:</p>
+
+<ul>
+
+<li>Apps such as games or movie apps may need to keep the screen turned on.</p>
+
+<li>Other applications may not need the screen to remain on, but they may require the CPU
+ to keep running until a critical operation finishes.</p>
+
+</ul>
+
+<p>
+This class describes how to keep a device awake when necessary without draining
+its battery.
+</p>
+<h2>Lessons</h2>
+
+<dl>
+ <dt>
+ <strong><a href="wakelock.html">Keeping the Device Awake</a></strong>
+ </dt>
+ <dd>
+ Learn how to keep the screen or CPU awake as needed, while minimizing the impact
+ on battery life.
+ </dd>
+ <dt>
+ <strong><a href="alarms.html">Scheduling Repeating Alarms</a></strong>
+ </dt>
+ <dd>
+ Learn how to use repeating alarms to schedule operations that take place outside
+ of the lifetime of the application, even if the application is not running and/or the
+ device is asleep.
+ </dd>
+</dl>
diff --git a/docs/html/training/scheduling/wakelock.jd b/docs/html/training/scheduling/wakelock.jd
new file mode 100644
index 0000000..0fab7be
--- /dev/null
+++ b/docs/html/training/scheduling/wakelock.jd
@@ -0,0 +1,215 @@
+page.title=Keeping the Device Awake
+
+trainingnavtop=true
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#screen">Keep the Screen On</a></li>
+ <li><a href="#cpu">Keep the CPU On</a></li>
+</ol>
+
+<h2>Try it out</h2>
+
+<div class="download-box">
+ <a href="{@docRoot}shareables/training/Scheduler.zip"
+class="button">Download the sample</a>
+ <p class="filename">Scheduler.zip</p>
+</div>
+
+</div>
+</div>
+
+
+<p>To avoid draining the battery, an Android device that is left idle quickly falls asleep.
+However, there are times when an application needs to wake up the screen or the CPU
+and keep it awake to complete some work.</p>
+
+<p>The approach you take depends on the needs of your app. However, a general rule of thumb
+is that you should use the most lightweight approach possible for your app, to minimize your
+app's impact on system resources. The following sections describe how to handle the cases
+where the device's default sleep behavior is incompatible with the requirements of your app.</p>
+
+<h2 id="screen">Keep the Screen On</h2>
+
+<p>Certain apps need to keep the screen turned on, such as games or movie apps. The best
+way to do this is to use the
+{@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON FLAG_KEEP_SCREEN_ON}
+in your activity (and only in an activity, never in a service or
+other app component). For example:</p>
+
+<pre>public class MainActivity extends Activity {
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ <strong>getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);</strong>
+ }</pre>
+
+<p>The advantage of this approach is that unlike wake locks (discussed in <a href="#cpu">
+Keep the CPU On</a>), it doesn't require special permission, and the platform correctly
+manages the user moving between applications, without your app needing to worry about
+releasing unused resources.</p>
+
+<p>Another way to implement this is in your application's layout XML file, by using the
+{@link android.R.attr#keepScreenOn android:keepScreenOn} attribute:</p>
+
+<pre>&lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ android:layout_width=&quot;match_parent&quot;
+ android:layout_height=&quot;match_parent&quot;
+ <strong>android:keepScreenOn=&quot;true&quot;&gt;</strong>
+ ...
+&lt;/RelativeLayout&gt;</pre>
+
+<p>Using <code>android:keepScreenOn=&quot;true&quot;</code> is equivalent to using
+{@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON FLAG_KEEP_SCREEN_ON}.
+You can use whichever approach is best for your app. The advantage of setting the flag
+programmatically in your activity is that it gives you the option of programmatically
+clearing the flag later and thereby allowing the screen to turn off.</p>
+
+<p class="note"><strong>Note:</strong> You don't need to clear the
+{@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON FLAG_KEEP_SCREEN_ON}
+flag unless you no longer want the screen to
+stay on in your running application (for example, if you want the screen to time out
+after a certain period of inactivity). The window manager takes care of
+ensuring that the right things happen when the app goes into the background or returns to
+the foreground. But if you want to explicitly clear the flag and thereby allow the screen to
+turn off again, use {@link android.view.Window#clearFlags clearFlags()}:
+{@code getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)}.</p>
+
+<h2 id="cpu">Keep the CPU On</h2>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h2>Alternatives to using wake locks</h2>
+
+<ul>
+
+<li>If your app is performing long-running HTTP downloads, consider using
+{@link android.app.DownloadManager}.</li>
+
+<li>If your app is synchronizing data from an external server, consider creating a
+<a href="{@docRoot}training/sync-adapters/index.html">sync
+adapter</a>.</li>
+
+<li>If your app relies on background services, consider using
+<a href="{@docRoot}training/scheduling/alarms.html">repeating alarms</a>
+or <a href="{@docRoot}google/gcm/index.html">Google Cloud Messaging</a> to trigger these
+services at specific intervals.</li>
+
+</ul>
+</div>
+</div>
+
+
+<p>If you need to keep the CPU running in order to complete some work before the device goes
+to sleep, you can use a {@link android.os.PowerManager} system service feature called
+wake locks. Wake locks allow your application to control the power state of the host device.</p>
+
+<p>Creating and holding wake locks can have a dramatic impact on the host device's battery
+life. Thus you should use wake locks only when strictly necessary
+and hold them for as short a time as possible. For example, you should never need to use a
+wake lock in an activity. As described above, if you want
+to keep the screen on in your activity, use
+{@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON FLAG_KEEP_SCREEN_ON}.</p>
+
+
+<p>One legitimate case for using a wake lock might be a background service
+that needs to grab a wake lock to keep the CPU running to do work while the screen is off.
+Again, though, this practice should be minimized because of its impact on battery life.</p>
+
+<p>To use a wake lock, the first step is to add the {@link android.Manifest.permission#WAKE_LOCK}
+ permission to your application's manifest file:</p>
+
+<pre>&lt;uses-permission android:name=&quot;android.permission.WAKE_LOCK&quot; /&gt;</pre>
+
+<p>If your app includes a broadcast receiver that uses a service to do some
+work, you can manage your wake lock through a
+{@link android.support.v4.content.WakefulBroadcastReceiver}, as described in
+<a href="#wakeful">Using a WakefulBroadcastReceiver</a>. This is the preferred approach.
+If your app doesn't follow that pattern, here is how you set a wake lock
+directly:</p>
+
+<pre>
+PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
+Wakelock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+ "MyWakelockTag");
+wakeLock.acquire();</pre>
+
+<p>To release the wake lock, call
+{@link android.os.PowerManager.WakeLock#release wakelock.release()}. This releases your
+claim to the CPU. It's important to release a wake lock as soon as your app is finished
+using it to avoid draining the battery.</p>
+
+<h3 id="wakeful">Using WakefulBroadcastReceiver</h3>
+
+<p>Using a broadcast receiver in conjunction with a service lets you manage the life cycle
+of a background task.</p>
+
+<p>A {@link android.support.v4.content.WakefulBroadcastReceiver} is a special type of
+broadcast receiver that takes care of
+creating and managing a
+{@link android.os.PowerManager#PARTIAL_WAKE_LOCK} for your app. A
+{@link android.support.v4.content.WakefulBroadcastReceiver}
+passes off the work to a {@link android.app.Service}
+(typically an
+{@link android.app.IntentService}), while ensuring that the device does not
+go back to sleep in the transition. If you don't hold a wake lock while transitioning
+the work to a service, you are effectively allowing the device to go back to sleep before
+the work completes. The net result is that the app might not finish doing the work until
+some arbitrary point in the future, which is not what you want.</p>
+
+<p>The first step in using a
+{@link android.support.v4.content.WakefulBroadcastReceiver} is to add it to your
+manifest, as with any other broadcast receiver:</p>
+
+<pre>&lt;receiver android:name=&quot;.MyWakefulReceiver&quot;&gt;&lt;/receiver&gt;</pre>
+
+<p>The following code starts {@code MyIntentService} with the method
+{@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()}.
+This method is comparable to {@link android.content.Context#startService startService()}, except that
+the {@link android.support.v4.content.WakefulBroadcastReceiver} is holding a
+wake lock when the service starts. The intent that is passed with
+{@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()}
+holds an extra identifying the wake lock:</p>
+
+<pre>public class MyWakefulReceiver extends WakefulBroadcastReceiver {
+
+ &#64;Override
+ public void onReceive(Context context, Intent intent) {
+
+ // Start the service, keeping the device awake while the service is
+ // launching. This is the Intent to deliver to the service.
+ Intent service = new Intent(context, MyIntentService.class);
+ startWakefulService(context, service);
+ }
+}</pre>
+
+<p>When the service is finished, it calls
+{@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent MyWakefulReceiver.completeWakefulIntent()}
+to release the wake lock. The
+{@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent completeWakefulIntent()}
+method has as its parameter the same intent that was
+passed in from the {@link android.support.v4.content.WakefulBroadcastReceiver}:</p>
+<pre>
+public class MyIntentService extends IntentService {
+ public static final int NOTIFICATION_ID = 1;
+ private NotificationManager mNotificationManager;
+ NotificationCompat.Builder builder;
+ public MyIntentService() {
+ super("MyIntentService");
+ }
+ &#64;Override
+ protected void onHandleIntent(Intent intent) {
+ Bundle extras = intent.getExtras();
+ // Do the work that requires your app to keep the CPU running.
+ // ...
+ // Release the wake lock provided by the WakefulBroadcastReceiver.
+ MyWakefulReceiver.completeWakefulIntent(intent);
+ }
+}</pre>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 0c4f9df..8b0e7f6 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -993,49 +993,13 @@ include the action bar on devices running Android 2.1 or higher."
<li class="nav-section">
<div class="nav-section-header">
- <a href="<?cs var:toroot ?>training/best-performance.html">
+ <a href="<?cs var:toroot ?>training/best-background.html">
<span class="small">Best Practices for</span><br/>
- Performance
+ Background Jobs
</a>
</div>
<ul>
- <li>
- <a href="<?cs var:toroot ?>training/articles/perf-tips.html"
- description=
- "How to optimize your app's performance in various ways to improve its
- responsiveness and battery efficiency."
- >Performance Tips</a>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>training/improving-layouts/index.html"
- description=
- "How to identify problems in your app's layout performance and improve the UI
- responsiveness."
- >Improving Layout Performance</a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot ?>training/improving-layouts/optimizing-layout.html">
- Optimizing Layout Hierarchies
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/improving-layouts/reusing-layouts.html">
- Re-using Layouts with &lt;include/&gt;
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/improving-layouts/loading-ondemand.html">
- Loading Views On Demand
- </a>
- </li>
- <li><a href="<?cs var:toroot ?>training/improving-layouts/smooth-scrolling.html">
- Making ListView Scrolling Smooth
- </a>
- </li>
- </ul>
- </li>
-
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>training/run-background-service/index.html"
@@ -1077,6 +1041,70 @@ include the action bar on devices running Android 2.1 or higher."
</ul>
</li>
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/scheduling/index.html"
+ description="How to use repeating alarms and wake locks
+ to run background jobs."
+ >Managing Device Awake State</a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/scheduling/wakelock.html">
+ Keeping the Device Awake</a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/scheduling/alarms.html">
+ Scheduling Repeating Alarms</a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li> <!-- end of Background Jobs -->
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/best-performance.html">
+ <span class="small">Best Practices for</span><br/>
+ Performance
+ </a>
+ </div>
+ <ul>
+
+ <li>
+ <a href="<?cs var:toroot ?>training/articles/perf-tips.html"
+ description=
+ "How to optimize your app's performance in various ways to improve its
+ responsiveness and battery efficiency."
+ >Performance Tips</a>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header">
+ <a href="<?cs var:toroot ?>training/improving-layouts/index.html"
+ description=
+ "How to identify problems in your app's layout performance and improve the UI
+ responsiveness."
+ >Improving Layout Performance</a>
+ </div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>training/improving-layouts/optimizing-layout.html">
+ Optimizing Layout Hierarchies
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/improving-layouts/reusing-layouts.html">
+ Re-using Layouts with &lt;include/&gt;
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/improving-layouts/loading-ondemand.html">
+ Loading Views On Demand
+ </a>
+ </li>
+ <li><a href="<?cs var:toroot ?>training/improving-layouts/smooth-scrolling.html">
+ Making ListView Scrolling Smooth
+ </a>
+ </li>
+ </ul>
+ </li>
+
<li class="nav-section">
<div class="nav-section-header">
<a href="/training/monitoring-device-state/index.html"