1page.title=Reporting Work Status
2trainingnavtop=true
3@jd:body
4<div id="tb-wrapper">
5<div id="tb">
6<h2>This lesson teaches you to</h2>
7<ol>
8    <li>
9        <a href="#ReportStatus">Report Status From an IntentService</a>
10    </li>
11    <li>
12        <a href="#ReceiveStatus">Receive Status Broadcasts from an IntentService</a>
13    </li>
14</ol>
15<h2>You should also read</h2>
16<ul>
17    <li>
18        <a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>
19    </li>
20    <li>
21        The section <b>Broadcast receivers</b> in the
22    <a href="{@docRoot}guide/components/fundamentals.html#Components">Application Components</a>
23        API guide.
24    </li>
25</ul>
26<h2>Try it out</h2>
27
28<div class="download-box">
29    <a href="{@docRoot}shareables/training/ThreadSample.zip" class="button">Download the sample</a>
30    <p class="filename">ThreadSample.zip</p>
31</div>
32
33</div>
34</div>
35<p>
36    This lesson shows you how to report the status of a work request run in a background service
37    to the component that sent the request. This allows you, for example, to report the status of
38    the request in an {@link android.app.Activity} object's UI. The recommended way to send and
39    receive status is to use a {@link android.support.v4.content.LocalBroadcastManager}, which
40    limits broadcast {@link android.content.Intent} objects to components in your own app.
41</p>
42<h2 id="ReportStatus">Report Status From an IntentService</h2>
43
44<p>
45    To send the status of a work request in an {@link android.app.IntentService} to other
46    components, first create an {@link android.content.Intent} that contains the status in its
47    extended data. As an option, you can add an action and data URI to this
48    {@link android.content.Intent}.
49</p>
50<p>
51    Next, send the {@link android.content.Intent} by calling
52    {@link android.support.v4.content.LocalBroadcastManager#sendBroadcast
53    LocalBroadcastManager.sendBroadcast()}. This sends the {@link android.content.Intent} to any
54    component in your application that has registered to receive it.
55    To get an instance of {@link android.support.v4.content.LocalBroadcastManager}, call
56    {@link android.support.v4.content.LocalBroadcastManager#getInstance getInstance()}.
57</p>
58<p>
59    For example:
60</p>
61<pre>
62public final class Constants {
63    ...
64    // Defines a custom Intent action
65    public static final String BROADCAST_ACTION =
66        "com.example.android.threadsample.BROADCAST";
67    ...
68    // Defines the key for the status "extra" in an Intent
69    public static final String EXTENDED_DATA_STATUS =
70        "com.example.android.threadsample.STATUS";
71    ...
72}
73public class RSSPullService extends IntentService {
74...
75    /*
76     * Creates a new Intent containing a Uri object
77     * BROADCAST_ACTION is a custom Intent action
78     */
79    Intent localIntent =
80            new Intent(Constants.BROADCAST_ACTION)
81            // Puts the status into the Intent
82            .putExtra(Constants.EXTENDED_DATA_STATUS, status);
83    // Broadcasts the Intent to receivers in this app.
84    LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
85...
86}
87</pre>
88<p>
89    The next step is to handle the incoming broadcast {@link android.content.Intent} objects in
90    the component that sent the original work request.
91</p>
92<h2 id="ReceiveStatus">Receive Status Broadcasts from an IntentService</h2>
93<p>
94
95    To receive broadcast {@link android.content.Intent} objects, use a subclass of
96    {@link android.content.BroadcastReceiver}. In the subclass, implement the
97    {@link android.content.BroadcastReceiver#onReceive BroadcastReceiver.onReceive()} callback
98    method, which {@link android.support.v4.content.LocalBroadcastManager} invokes when it receives
99    an {@link android.content.Intent}. {@link android.support.v4.content.LocalBroadcastManager}
100    passes the incoming {@link android.content.Intent} to
101    {@link android.content.BroadcastReceiver#onReceive BroadcastReceiver.onReceive()}.
102</p>
103<p>
104    For example:
105</p>
106<pre>
107// Broadcast receiver for receiving status updates from the IntentService
108private class ResponseReceiver extends BroadcastReceiver
109{
110    // Prevents instantiation
111    private DownloadStateReceiver() {
112    }
113    // Called when the BroadcastReceiver gets an Intent it's registered to receive
114    &#64;
115    public void onReceive(Context context, Intent intent) {
116...
117        /*
118         * Handle Intents here.
119         */
120...
121    }
122}
123</pre>
124<p>
125    Once you've defined the {@link android.content.BroadcastReceiver}, you can define filters
126    for it that match specific actions, categories, and data. To do this, create
127    an {@link android.content.IntentFilter}. This first snippet shows how to define the filter:
128</p>
129<pre>
130// Class that displays photos
131public class DisplayActivity extends FragmentActivity {
132    ...
133    public void onCreate(Bundle stateBundle) {
134        ...
135        super.onCreate(stateBundle);
136        ...
137        // The filter's action is BROADCAST_ACTION
138        IntentFilter mStatusIntentFilter = new IntentFilter(
139                Constants.BROADCAST_ACTION);
140
141        // Adds a data filter for the HTTP scheme
142        mStatusIntentFilter.addDataScheme("http");
143        ...
144</pre>
145<p>
146    To register the {@link android.content.BroadcastReceiver} and the
147    {@link android.content.IntentFilter} with the system, get an instance of
148    {@link android.support.v4.content.LocalBroadcastManager} and call its
149    {@link android.support.v4.content.LocalBroadcastManager#registerReceiver registerReceiver()}
150    method. This next snippet shows how to register the {@link android.content.BroadcastReceiver}
151    and its {@link android.content.IntentFilter}:
152</p>
153<pre>
154        // Instantiates a new DownloadStateReceiver
155        DownloadStateReceiver mDownloadStateReceiver =
156                new DownloadStateReceiver();
157        // Registers the DownloadStateReceiver and its intent filters
158        LocalBroadcastManager.getInstance(this).registerReceiver(
159                mDownloadStateReceiver,
160                mStatusIntentFilter);
161        ...
162</pre>
163<p>
164    A single {@link android.content.BroadcastReceiver} can handle more than one type of broadcast
165    {@link android.content.Intent} object, each with its own action. This feature allows you to
166    run different code for each action, without having to define a separate
167    {@link android.content.BroadcastReceiver} for each action. To define another
168    {@link android.content.IntentFilter} for the same
169    {@link android.content.BroadcastReceiver}, create the {@link android.content.IntentFilter} and
170    repeat the call to
171    {@link android.support.v4.content.LocalBroadcastManager#registerReceiver registerReceiver()}.
172    For example:
173</p>
174<pre>
175        /*
176         * Instantiates a new action filter.
177         * No data filter is needed.
178         */
179        statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE);
180        ...
181        // Registers the receiver with the new filter
182        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
183                mDownloadStateReceiver,
184                mIntentFilter);
185</pre>
186<p>
187    Sending an broadcast {@link android.content.Intent} doesn't start or resume an
188    {@link android.app.Activity}. The {@link android.content.BroadcastReceiver} for an
189    {@link android.app.Activity} receives and processes {@link android.content.Intent} objects even
190    when your app is in the background, but doesn't force your app to the foreground. If you
191    want to notify the user about an event that happened in the background while your app was not
192    visible, use a {@link android.app.Notification}. <i>Never</i> start an
193    {@link android.app.Activity} in response to an incoming broadcast
194    {@link android.content.Intent}.
195</p>
196<p>
197
198</p>
199
200