1 page.title=Starting Another Activity 2 parent.title=Building Your First App 3 parent.link=index.html 4 5 trainingnavtop=true 6 previous.title=Building a Simpler User Interface 7 previous.link=building-ui.html 8 9 @jd:body 10 11 12 <!-- This is the training bar --> 13 <div id="tb-wrapper"> 14 <div id="tb"> 15 16 <h2>This lesson teaches you to</h2> 17 18 <ol> 19 <li><a href="#RespondToButton">Respond to the Send Button</a></li> 20 <li><a href="#BuildIntent">Build an Intent</a></li> 21 <li><a href="#StartActivity">Start the Second Activity</a></li> 22 <li><a href="#CreateActivity">Create the Second Activity</a></li> 23 <li><a href="#ReceiveIntent">Receive the Intent</a></li> 24 <li><a href="#DisplayMessage">Display the Message</a></li> 25 </ol> 26 27 <h2>You should also read</h2> 28 29 <ul> 30 <li><a href="{@docRoot}sdk/installing/index.html">Installing the 31 SDK</a></li> 32 </ul> 33 34 35 </div> 36 </div> 37 38 39 40 <p>After completing the <a href="building-ui.html">previous lesson</a>, you have an app that 41 shows an activity (a single screen) with a text field and a button. In this lesson, youll add some 42 code to <code>MainActivity</code> that 43 starts a new activity when the user clicks the Send button.</p> 44 45 46 <h2 id="RespondToButton">Respond to the Send Button</h2> 47 48 <p>To respond to the button's on-click event, open the <code>activity_main.xml</code> 49 layout file and add the <a 50 href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a> 51 attribute to the {@link android.widget.Button <Button>} element:</p> 52 53 <pre> 54 <Button 55 android:layout_width="wrap_content" 56 android:layout_height="wrap_content" 57 android:text="@string/button_send" 58 android:onClick="sendMessage" /> 59 </pre> 60 61 <p>The <a 62 href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code 63 android:onClick}</a> attributes value, <code>"sendMessage"</code>, is the name of a method in your 64 activity that the system calls when the user clicks the button.</p> 65 66 <p>Open the <code>MainActivity</code> class (located in the project's 67 <code>src/</code> directory) and add the corresponding method:</p> 68 69 <pre> 70 /** Called when the user clicks the Send button */ 71 public void sendMessage(View view) { 72 // Do something in response to button 73 } 74 </pre> 75 76 <p>This requires that you import the {@link android.view.View} class:</p> 77 <pre> 78 import android.view.View; 79 </pre> 80 81 <p class="note"><strong>Tip:</strong> In Eclipse, press Ctrl + Shift + O to import missing classes 82 (Cmd + Shift + O on Mac).</p> 83 84 <p>In order for the system to match this method to the method name given to <a 85 href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>, 86 the signature must be exactly as shown. Specifically, the method must:</p> 87 88 <ul> 89 <li>Be public</li> 90 <li>Have a void return value</li> 91 <li>Have a {@link android.view.View} as the only parameter (this will be the {@link 92 android.view.View} that was clicked)</li> 93 </ul> 94 95 <p>Next, youll fill in this method to read the contents of the text field and deliver that text to 96 another activity.</p> 97 98 99 100 <h2 id="BuildIntent">Build an Intent</h2> 101 102 <p>An {@link android.content.Intent} is an object that provides runtime binding between separate 103 components (such as two activities). The {@link android.content.Intent} represents an 104 apps "intent to do something." You can use intents for a wide 105 variety of tasks, but most often theyre used to start another activity.</p> 106 107 <p>Inside the {@code sendMessage()} method, create an {@link android.content.Intent} to start 108 an activity called {@code DisplayMessageActivity}:</p> 109 110 <pre> 111 Intent intent = new Intent(this, DisplayMessageActivity.class); 112 </pre> 113 114 <p>The constructor used here takes two parameters:</p> 115 <ul> 116 <li>A {@link 117 android.content.Context} as its first parameter ({@code this} is used because the {@link 118 android.app.Activity} class is a subclass of {@link android.content.Context}) 119 <li>The {@link java.lang.Class} of the app component to which the system should deliver 120 the {@link android.content.Intent} (in this case, the activity that should be started) 121 </ul> 122 123 <div class="sidebox-wrapper"> 124 <div class="sidebox"> 125 <h3>Sending an intent to other apps</h3> 126 <p>The intent created in this lesson is what's considered an <em>explicit intent</em>, because the 127 {@link android.content.Intent} 128 specifies the exact app component to which the intent should be given. However, intents 129 can also be <em>implicit</em>, in which case the {@link android.content.Intent} does not specify 130 the desired component, but allows any app installed on the device to respond to the intent 131 as long as it satisfies the meta-data specifications for the action that's specified in various 132 {@link android.content.Intent} parameters. For more information, see the class about <a 133 href="{@docRoot}training/basics/intents/index.html">Interacting with Other Apps</a>.</p> 134 </div> 135 </div> 136 137 <p class="note"><strong>Note:</strong> The reference to {@code DisplayMessageActivity} 138 will raise an error if youre using an IDE such as Eclipse because the class doesnt exist yet. 139 Ignore the error for now; youll create the class soon.</p> 140 141 <p>An intent not only allows you to start another activity, but it can carry a bundle of data to the 142 activity as well. Inside the {@code sendMessage()} method, 143 use {@link android.app.Activity#findViewById findViewById()} to get the 144 {@link android.widget.EditText} element and add its text value to the intent:</p> 145 146 <pre> 147 Intent intent = new Intent(this, DisplayMessageActivity.class); 148 EditText editText = (EditText) findViewById(R.id.edit_message); 149 String message = editText.getText().toString(); 150 intent.putExtra(EXTRA_MESSAGE, message); 151 </pre> 152 153 <p class="note"><strong>Note:</strong> 154 You now need import statements for <code>android.content.Intent</code> 155 and <code>android.widget.EditText</code>. You'll define the <code>EXTRA_MESSAGE</code> 156 constant in a moment.</p> 157 158 <p>An {@link android.content.Intent} can carry a collection of various data types as key-value 159 pairs called <em>extras</em>. The {@link android.content.Intent#putExtra putExtra()} method takes the 160 key name in the first parameter and the value in the second parameter.</p> 161 162 <p>In order for the next activity to query the extra data, you should define the key 163 for your intent's extra using a 164 public constant. So add the {@code EXTRA_MESSAGE} definition to the top of the {@code 165 MainActivity} class:</p> 166 167 <pre> 168 public class MainActivity extends Activity { 169 public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"; 170 ... 171 } 172 </pre> 173 174 <p>It's generally a good practice to define keys for intent extras using your app's package name 175 as a prefix. This ensures they are unique, in case your app interacts with other apps.</p> 176 177 178 179 180 <h2 id="StartActivity">Start the Second Activity</h2> 181 182 <p>To start an activity, call {@link android.app.Activity#startActivity 183 startActivity()} and pass it your {@link android.content.Intent}. The system receives this call 184 and starts an instance of the {@link android.app.Activity} 185 specified by the {@link android.content.Intent}.</p> 186 187 <p>With this new code, the complete {@code sendMessage()} method that's invoked by the Send 188 button now looks like this:</p> 189 190 <pre> 191 /** Called when the user clicks the Send button */ 192 public void sendMessage(View view) { 193 Intent intent = new Intent(this, DisplayMessageActivity.class); 194 EditText editText = (EditText) findViewById(R.id.edit_message); 195 String message = editText.getText().toString(); 196 intent.putExtra(EXTRA_MESSAGE, message); 197 startActivity(intent); 198 } 199 </pre> 200 201 <p>Now you need to create the {@code DisplayMessageActivity} class in order for this to 202 work.</p> 203 204 205 206 <h2 id="CreateActivity">Create the Second Activity</h2> 207 208 <div class="figure" style="width:400px"> 209 <img src="{@docRoot}images/training/firstapp/adt-new-activity.png" alt="" /> 210 <p class="img-caption"><strong>Figure 1.</strong> The new activity wizard in Eclipse.</p> 211 </div> 212 213 <p>To create a new activity using Eclipse:</p> 214 215 <ol> 216 <li>Click <strong>New</strong> <img src="{@docRoot}images/tools/eclipse-new.png" 217 style="vertical-align:baseline;margin:0" /> in the toolbar.</li> 218 <li>In the window that appears, open the <strong>Android</strong> folder 219 and select <strong>Android Activity</strong>. Click <strong>Next</strong>.</li> 220 <li>Select <strong>BlankActivity</strong> and click <strong>Next</strong>.</li> 221 <li>Fill in the activity details: 222 <ul> 223 <li><strong>Project</strong>: MyFirstApp</li> 224 <li><strong>Activity Name</strong>: DisplayMessageActivity</li> 225 <li><strong>Layout Name</strong>: activity_display_message</li> 226 <li><strong>Title</strong>: My Message</li> 227 <li><strong>Hierarchial Parent</strong>: com.example.myfirstapp.MainActivity</li> 228 <li><strong>Navigation Type</strong>: None</li> 229 </ul> 230 <p>Click <strong>Finish</strong>.</p> 231 </li> 232 </ol> 233 234 <p>If you're using a different IDE or the command line tools, create a new file named 235 {@code DisplayMessageActivity.java} in the project's <code>src/</code> directory, next to 236 the original {@code MainActivity.java} file.</p> 237 238 <p>Open the {@code DisplayMessageActivity.java} file. If you used Eclipse to create this 239 activity:</p> 240 <ul> 241 <li>The class 242 already includes an implementation of the required {@link android.app.Activity#onCreate onCreate()} 243 method.</li> 244 <li>There's also an implementation of the {@link android.app.Activity#onCreateOptionsMenu 245 onCreateOptionsMenu()} method, but 246 you won't need it for this app so you can remove it.</li> 247 <li>There's also an implementation of {@link android.app.Activity#onOptionsItemSelected 248 onOptionsItemSelected()} which handles the behavior for the action bar's <em>Up</em> behavior. 249 Keep this one the way it is.</li> 250 </ul> 251 252 <p>Because the {@link android.app.ActionBar} APIs are available only on {@link 253 android.os.Build.VERSION_CODES#HONEYCOMB} (API level 11) and higher, you must add a condition 254 around the {@link android.app.Activity#getActionBar()} method to check the current platform version. 255 Additionally, you must add the {@code @SuppressLint("NewApi")} tag to the 256 {@link android.app.Activity#onCreate onCreate()} method to avoid <a 257 href="{@docRoot}tools/help/lint.html">lint</a> errors.</p> 258 259 <p>The {@code DisplayMessageActivity} class should now look like this:</p> 260 261 <pre> 262 public class DisplayMessageActivity extends Activity { 263 264 @SuppressLint("NewApi") 265 @Override 266 protected void onCreate(Bundle savedInstanceState) { 267 super.onCreate(savedInstanceState); 268 setContentView(R.layout.activity_display_message); 269 270 // Make sure we're running on Honeycomb or higher to use ActionBar APIs 271 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 272 // Show the Up button in the action bar. 273 getActionBar().setDisplayHomeAsUpEnabled(true); 274 } 275 } 276 277 @Override 278 public boolean onOptionsItemSelected(MenuItem item) { 279 switch (item.getItemId()) { 280 case android.R.id.home: 281 NavUtils.navigateUpFromSameTask(this); 282 return true; 283 } 284 return super.onOptionsItemSelected(item); 285 } 286 } 287 </pre> 288 289 <p>If you used an IDE other than Eclipse, update your {@code DisplayMessageActivity} 290 class with the above code.</p> 291 292 <p>All subclasses of {@link android.app.Activity} must implement the {@link 293 android.app.Activity#onCreate onCreate()} method. The system calls this when creating a new 294 instance of the activity. This method is where you must define the activity layout 295 with the {@link android.app.Activity#setContentView setContentView()} method 296 and is where you should 297 perform initial setup for the activity components.</p> 298 299 <p class="note"><strong>Note:</strong> If you are using an IDE other than Eclipse, your project 300 does not contain the {@code activity_display_message} layout that's requested by 301 {@link android.app.Activity#setContentView setContentView()}. That's OK because 302 you will update this method later and won't be using that layout.</p> 303 304 305 <h3 id="AddTitle">Add the title string</h3> 306 307 <p>If you used Eclipse, you can skip to the <a href="#AddToManifest">next section</a>, 308 because the template provides 309 the title string for the new activity.</p> 310 311 <p>If you're using an IDE other than Eclipse, 312 add the new activity's title to the {@code strings.xml} file:</p> 313 <pre> 314 <resources> 315 ... 316 <string name="title_activity_display_message">My Message</string> 317 </resources> 318 </pre> 319 320 321 322 <h3 id="AddToManifest">Add it to the manifest</h3> 323 324 <p>All activities must be declared in your manifest file, <code>AndroidManifest.xml</code>, using an 325 <a 326 href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element.</p> 327 328 <p>When you use the Eclipse tools to create the activity, it creates a default entry. If you're 329 using a different IDE, you need to add the manifest entry yourself. It should 330 look like this:</p> 331 332 <pre> 333 <application ... > 334 ... 335 <activity 336 android:name="com.example.myfirstapp.DisplayMessageActivity" 337 android:label="@string/title_activity_display_message" 338 android:parentActivityName="com.example.myfirstapp.MainActivity" > 339 <meta-data 340 android:name="android.support.PARENT_ACTIVITY" 341 android:value="com.example.myfirstapp.MainActivity" /> 342 </activity> 343 </application> 344 </pre> 345 346 <p>The <a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code 347 android:parentActivityName}</a> attribute declares the name of this activity's parent activity 348 within the app's logical hierarchy. The system uses this value 349 to implement default navigation behaviors, such as <a 350 href="{@docRoot}design/patterns/navigation.html">Up navigation</a> on 351 Android 4.1 (API level 16) and higher. You can provide the same navigation behaviors for 352 older versions of Android by using the 353 <a href="{@docRoot}tools/support-library/index.html">Support Library</a> and adding 354 the <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code 355 <meta-data>}</a> element as shown here.</p> 356 357 <p class="note"><strong>Note:</strong> Your Android SDK should already include 358 the latest Android Support Library. It's included with the ADT Bundle but if you're using 359 a different IDE, you should have installed it during the 360 <a href="{@docRoot}sdk/installing/adding-packages.html">Adding Platforms and Packages</a> step. 361 When using the templates in Eclipse, the Support Library is automatically added to your app project 362 (you can see the library's JAR file listed under <em>Android Dependencies</em>). If you're not using 363 Eclipse, you need to manually add the library to your project—follow the guide for <a 364 href="{@docRoot}tools/support-library/setup.html">setting up the Support Library</a> 365 then return here.</p> 366 367 <p>If you're developing with Eclipse, you can run the app now, but not much happens. 368 Clicking the Send button starts the second activity but it uses 369 a default "Hello world" layout provided by the template. You'll soon update the 370 activity to instead display a custom text view, so if you're using a different IDE, 371 don't worry that the app won't yet compile.</p> 372 373 374 <h2 id="ReceiveIntent">Receive the Intent</h2> 375 376 <p>Every {@link android.app.Activity} is invoked by an {@link android.content.Intent}, regardless of 377 how the user navigated there. You can get the {@link android.content.Intent} that started your 378 activity by calling {@link android.app.Activity#getIntent()} and retrieve the data contained 379 within it.</p> 380 381 <p>In the {@code DisplayMessageActivity} classs {@link android.app.Activity#onCreate onCreate()} 382 method, get the intent and extract the message delivered by {@code MainActivity}:</p> 383 384 <pre> 385 Intent intent = getIntent(); 386 String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); 387 </pre> 388 389 390 391 <h2 id="DisplayMessage">Display the Message</h2> 392 393 <p>To show the message on the screen, create a {@link android.widget.TextView} widget and set the 394 text using {@link android.widget.TextView#setText setText()}. Then add the {@link 395 android.widget.TextView} as the root view of the activitys layout by passing it to {@link 396 android.app.Activity#setContentView setContentView()}.</p> 397 398 <p>The complete {@link android.app.Activity#onCreate onCreate()} method for {@code 399 DisplayMessageActivity} now looks like this:</p> 400 401 <pre> 402 @Override 403 public void onCreate(Bundle savedInstanceState) { 404 super.onCreate(savedInstanceState); 405 406 // Get the message from the intent 407 Intent intent = getIntent(); 408 String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); 409 410 // Create the text view 411 TextView textView = new TextView(this); 412 textView.setTextSize(40); 413 textView.setText(message); 414 415 // Set the text view as the activity layout 416 setContentView(textView); 417 } 418 </pre> 419 420 <p>You can now run the app. When it opens, type a message in the text field, click Send, 421 and the message appears on the second activity.</p> 422 423 <img src="{@docRoot}images/training/firstapp/firstapp.png" /> 424 <p class="img-caption"><strong>Figure 2.</strong> Both activities in the final app, running 425 on Android 4.0. 426 427 <p>That's it, you've built your first Android app!</p> 428 429 <p>To learn more, follow the link below to the next class.</p> 430 431 432 433 434