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>fragment_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>In order for the system to match this method to the method name given to <a 77 href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>, 78 the signature must be exactly as shown. Specifically, the method must:</p> 79 80 <ul> 81 <li>Be public</li> 82 <li>Have a void return value</li> 83 <li>Have a {@link android.view.View} as the only parameter (this will be the {@link 84 android.view.View} that was clicked)</li> 85 </ul> 86 87 <p>Next, youll fill in this method to read the contents of the text field and deliver that text to 88 another activity.</p> 89 90 91 92 <h2 id="BuildIntent">Build an Intent</h2> 93 94 <p>An {@link android.content.Intent} is an object that provides runtime binding between separate 95 components (such as two activities). The {@link android.content.Intent} represents an 96 apps "intent to do something." You can use intents for a wide 97 variety of tasks, but most often theyre used to start another activity.</p> 98 99 <p>Inside the {@code sendMessage()} method, create an {@link android.content.Intent} to start 100 an activity called {@code DisplayMessageActivity}:</p> 101 102 <pre> 103 Intent intent = new Intent(this, DisplayMessageActivity.class); 104 </pre> 105 106 <p>This requires that you import the {@link android.content.Intent} class:</p> 107 <pre> 108 import android.content.Intent; 109 </pre> 110 111 <p class="note"><strong>Tip:</strong> In Eclipse, press Ctrl + Shift + O to import missing classes 112 (Cmd + Shift + O on Mac).</p> 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 an import statement for <code>android.widget.EditText</code>. 155 You'll define the <code>EXTRA_MESSAGE</code> constant in a moment.</p> 156 157 <p>An {@link android.content.Intent} can carry a collection of various data types as key-value 158 pairs called <em>extras</em>. The {@link android.content.Intent#putExtra putExtra()} method takes the 159 key name in the first parameter and the value in the second parameter.</p> 160 161 <p>In order for the next activity to query the extra data, you should define the key 162 for your intent's extra using a 163 public constant. So add the {@code EXTRA_MESSAGE} definition to the top of the {@code 164 MainActivity} class:</p> 165 166 <pre> 167 public class MainActivity extends ActionBarActivity { 168 public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"; 169 ... 170 } 171 </pre> 172 173 <p>It's generally a good practice to define keys for intent extras using your app's package name 174 as a prefix. This ensures they are unique, in case your app interacts with other apps.</p> 175 176 177 178 179 <h2 id="StartActivity">Start the Second Activity</h2> 180 181 <p>To start an activity, call {@link android.app.Activity#startActivity 182 startActivity()} and pass it your {@link android.content.Intent}. The system receives this call 183 and starts an instance of the {@link android.app.Activity} 184 specified by the {@link android.content.Intent}.</p> 185 186 <p>With this new code, the complete {@code sendMessage()} method that's invoked by the Send 187 button now looks like this:</p> 188 189 <pre> 190 /** Called when the user clicks the Send button */ 191 public void sendMessage(View view) { 192 Intent intent = new Intent(this, DisplayMessageActivity.class); 193 EditText editText = (EditText) findViewById(R.id.edit_message); 194 String message = editText.getText().toString(); 195 intent.putExtra(EXTRA_MESSAGE, message); 196 startActivity(intent); 197 } 198 </pre> 199 200 <p>Now you need to create the {@code DisplayMessageActivity} class in order for this to 201 work.</p> 202 203 204 205 <h2 id="CreateActivity">Create the Second Activity</h2> 206 207 <div class="figure" style="width:400px"> 208 <img src="{@docRoot}images/training/firstapp/adt-new-activity.png" alt="" /> 209 <p class="img-caption"><strong>Figure 1.</strong> The new activity wizard in Eclipse.</p> 210 </div> 211 212 <p>To create a new activity using Eclipse:</p> 213 214 <ol> 215 <li>Click <strong>New</strong> <img src="{@docRoot}images/tools/eclipse-new.png" 216 style="vertical-align:baseline;margin:0" /> in the toolbar.</li> 217 <li>In the window that appears, open the <strong>Android</strong> folder 218 and select <strong>Android Activity</strong>. Click <strong>Next</strong>.</li> 219 <li>Select <strong>BlankActivity</strong> and click <strong>Next</strong>.</li> 220 <li>Fill in the activity details: 221 <ul> 222 <li><strong>Project</strong>: MyFirstApp</li> 223 <li><strong>Activity Name</strong>: DisplayMessageActivity</li> 224 <li><strong>Layout Name</strong>: activity_display_message</li> 225 <li><strong>Fragment Layout Name</strong>: fragment_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. You will update the implementation of this method later.</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 <li>There's also a <code>PlaceholderFragment</code> class that extends 251 {@link android.app.Fragment}. You will not need this class in the final version of this 252 activity.</li> 253 </ul> 254 255 <p>Fragments decompose application functionality and UI into reusable modules. For more 256 information on fragments, see the <a href="{@docRoot}guide/components/fragments.html">Fragments 257 API Guide</a>. The final version of this activity does not use fragments.</p> 258 259 <p class="note"><strong>Note:</strong> Your activity may look different if you did not use 260 the latest version of the ADT plugin. Make sure you install the latest version of the 261 <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT plugin</a> to complete this tutorial.</p> 262 263 <p>The {@code DisplayMessageActivity} class should now look like this:</p> 264 265 <pre> 266 public class DisplayMessageActivity extends ActionBarActivity { 267 268 @Override 269 protected void onCreate(Bundle savedInstanceState) { 270 super.onCreate(savedInstanceState); 271 setContentView(R.layout.activity_display_message); 272 273 if (savedInstanceState == null) { 274 getSupportFragmentManager().beginTransaction() 275 .add(R.id.container, new PlaceholderFragment()).commit(); 276 } 277 } 278 279 @Override 280 public boolean onOptionsItemSelected(MenuItem item) { 281 // Handle action bar item clicks here. The action bar will 282 // automatically handle clicks on the Home/Up button, so long 283 // as you specify a parent activity in AndroidManifest.xml. 284 int id = item.getItemId(); 285 if (id == R.id.action_settings) { 286 return true; 287 } 288 return super.onOptionsItemSelected(item); 289 } 290 291 /** 292 * A placeholder fragment containing a simple view. 293 */ 294 public static class PlaceholderFragment extends Fragment { 295 296 public PlaceholderFragment() { } 297 298 @Override 299 public View onCreateView(LayoutInflater inflater, ViewGroup container, 300 Bundle savedInstanceState) { 301 View rootView = inflater.inflate(R.layout.fragment_display_message, 302 container, false); 303 return rootView; 304 } 305 } 306 } 307 </pre> 308 309 <p>If you used an IDE other than Eclipse, update your {@code DisplayMessageActivity} 310 class with the above code.</p> 311 312 <p>All subclasses of {@link android.app.Activity} must implement the {@link 313 android.app.Activity#onCreate onCreate()} method. The system calls this when creating a new 314 instance of the activity. This method is where you must define the activity layout 315 with the {@link android.app.Activity#setContentView setContentView()} method 316 and is where you should 317 perform initial setup for the activity components.</p> 318 319 <p class="note"><strong>Note:</strong> If you are using an IDE other than Eclipse, your project 320 does not contain the {@code activity_display_message} layout that's requested by 321 {@link android.app.Activity#setContentView setContentView()}. That's OK because 322 you will update this method later and won't be using that layout.</p> 323 324 325 <h3 id="AddTitle">Add the title string</h3> 326 327 <p>If you used Eclipse, you can skip to the <a href="#AddToManifest">next section</a>, 328 because the template provides 329 the title string for the new activity.</p> 330 331 <p>If you're using an IDE other than Eclipse, 332 add the new activity's title to the {@code strings.xml} file:</p> 333 <pre> 334 <resources> 335 ... 336 <string name="title_activity_display_message">My Message</string> 337 </resources> 338 </pre> 339 340 341 342 <h3 id="AddToManifest">Add it to the manifest</h3> 343 344 <p>All activities must be declared in your manifest file, <code>AndroidManifest.xml</code>, using an 345 <a 346 href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element.</p> 347 348 <p>When you use the Eclipse tools to create the activity, it creates a default entry. If you're 349 using a different IDE, you need to add the manifest entry yourself. It should 350 look like this:</p> 351 352 <pre> 353 <application ... > 354 ... 355 <activity 356 android:name="com.example.myfirstapp.DisplayMessageActivity" 357 android:label="@string/title_activity_display_message" 358 android:parentActivityName="com.example.myfirstapp.MainActivity" > 359 <meta-data 360 android:name="android.support.PARENT_ACTIVITY" 361 android:value="com.example.myfirstapp.MainActivity" /> 362 </activity> 363 </application> 364 </pre> 365 366 <p>The <a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code 367 android:parentActivityName}</a> attribute declares the name of this activity's parent activity 368 within the app's logical hierarchy. The system uses this value 369 to implement default navigation behaviors, such as <a 370 href="{@docRoot}design/patterns/navigation.html">Up navigation</a> on 371 Android 4.1 (API level 16) and higher. You can provide the same navigation behaviors for 372 older versions of Android by using the 373 <a href="{@docRoot}tools/support-library/index.html">Support Library</a> and adding 374 the <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code 375 <meta-data>}</a> element as shown here.</p> 376 377 <p class="note"><strong>Note:</strong> Your Android SDK should already include 378 the latest Android Support Library. It's included with the ADT Bundle but if you're using 379 a different IDE, you should have installed it during the 380 <a href="{@docRoot}sdk/installing/adding-packages.html">Adding Platforms and Packages</a> step. 381 When using the templates in Eclipse, the Support Library is automatically added to your app project 382 (you can see the library's JAR file listed under <em>Android Dependencies</em>). If you're not using 383 Eclipse, you need to manually add the library to your project—follow the guide for <a 384 href="{@docRoot}tools/support-library/setup.html">setting up the Support Library</a> 385 then return here.</p> 386 387 <p>If you're developing with Eclipse, you can run the app now, but not much happens. 388 Clicking the Send button starts the second activity but it uses 389 a default "Hello world" layout provided by the template. You'll soon update the 390 activity to instead display a custom text view, so if you're using a different IDE, 391 don't worry that the app won't yet compile.</p> 392 393 394 <h2 id="ReceiveIntent">Receive the Intent</h2> 395 396 <p>Every {@link android.app.Activity} is invoked by an {@link android.content.Intent}, regardless of 397 how the user navigated there. You can get the {@link android.content.Intent} that started your 398 activity by calling {@link android.app.Activity#getIntent()} and retrieve the data contained 399 within it.</p> 400 401 <p>In the {@code DisplayMessageActivity} classs {@link android.app.Activity#onCreate onCreate()} 402 method, get the intent and extract the message delivered by {@code MainActivity}:</p> 403 404 <pre> 405 Intent intent = getIntent(); 406 String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); 407 </pre> 408 409 410 411 <h2 id="DisplayMessage">Display the Message</h2> 412 413 <p>To show the message on the screen, create a {@link android.widget.TextView} widget and set the 414 text using {@link android.widget.TextView#setText setText()}. Then add the {@link 415 android.widget.TextView} as the root view of the activitys layout by passing it to {@link 416 android.app.Activity#setContentView setContentView()}.</p> 417 418 <p>The complete {@link android.app.Activity#onCreate onCreate()} method for {@code 419 DisplayMessageActivity} now looks like this:</p> 420 421 <pre> 422 @Override 423 public void onCreate(Bundle savedInstanceState) { 424 super.onCreate(savedInstanceState); 425 426 // Get the message from the intent 427 Intent intent = getIntent(); 428 String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); 429 430 // Create the text view 431 TextView textView = new TextView(this); 432 textView.setTextSize(40); 433 textView.setText(message); 434 435 // Set the text view as the activity layout 436 setContentView(textView); 437 } 438 </pre> 439 440 <p>You can now run the app. When it opens, type a message in the text field, click Send, 441 and the message appears on the second activity.</p> 442 443 <img src="{@docRoot}images/training/firstapp/firstapp.png" /> 444 <p class="img-caption"><strong>Figure 2.</strong> Both activities in the final app, running 445 on Android 4.4. 446 447 <p>That's it, you've built your first Android app!</p> 448 449 <p>To learn more, follow the link below to the next class.</p> 450 451 452 453 454