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 @ 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