page.title=Starting Another Activity parent.title=Building Your First App parent.link=index.html trainingnavtop=true previous.title=Building a Simpler User Interface previous.link=building-ui.html @jd:body <!-- This is the training bar --> <div id="tb-wrapper"> <div id="tb"> <h2>This lesson teaches you to</h2> <ol> <li><a href="#RespondToButton">Respond to the Send Button</a></li> <li><a href="#BuildIntent">Build an Intent</a></li> <li><a href="#StartActivity">Start the Second Activity</a></li> <li><a href="#CreateActivity">Create the Second Activity</a></li> <li><a href="#ReceiveIntent">Receive the Intent</a></li> <li><a href="#DisplayMessage">Display the Message</a></li> </ol> <h2>You should also read</h2> <ul> <li><a href="{@docRoot}sdk/installing/index.html">Installing the SDK</a></li> </ul> </div> </div> <p>After completing the <a href="building-ui.html">previous lesson</a>, you have an app that shows an activity (a single screen) with a text field and a button. In this lesson, you’ll add some code to <code>MainActivity</code> that starts a new activity when the user clicks the Send button.</p> <h2 id="RespondToButton">Respond to the Send Button</h2> <p>To respond to the button's on-click event, open the <code>fragment_main.xml</code> layout file and add the <a href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a> attribute to the {@link android.widget.Button <Button>} element:</p> <pre> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_send" android:onClick="sendMessage" /> </pre> <p>The <a href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a> attribute’s value, <code>"sendMessage"</code>, is the name of a method in your activity that the system calls when the user clicks the button.</p> <p>Open the <code>MainActivity</code> class (located in the project's <code>src/</code> directory) and add the corresponding method:</p> <pre> /** Called when the user clicks the Send button */ public void sendMessage(View view) { // Do something in response to button } </pre> <p>In order for the system to match this method to the method name given to <a href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>, the signature must be exactly as shown. Specifically, the method must:</p> <ul> <li>Be public</li> <li>Have a void return value</li> <li>Have a {@link android.view.View} as the only parameter (this will be the {@link android.view.View} that was clicked)</li> </ul> <p>Next, you’ll fill in this method to read the contents of the text field and deliver that text to another activity.</p> <h2 id="BuildIntent">Build an Intent</h2> <p>An {@link android.content.Intent} is an object that provides runtime binding between separate components (such as two activities). The {@link android.content.Intent} represents an app’s "intent to do something." You can use intents for a wide variety of tasks, but most often they’re used to start another activity.</p> <p>Inside the {@code sendMessage()} method, create an {@link android.content.Intent} to start an activity called {@code DisplayMessageActivity}:</p> <pre> Intent intent = new Intent(this, DisplayMessageActivity.class); </pre> <p>This requires that you import the {@link android.content.Intent} class:</p> <pre> import android.content.Intent; </pre> <p class="note"><strong>Tip:</strong> In Eclipse, press Ctrl + Shift + O to import missing classes (Cmd + Shift + O on Mac).</p> <p>The constructor used here takes two parameters:</p> <ul> <li>A {@link android.content.Context} as its first parameter ({@code this} is used because the {@link android.app.Activity} class is a subclass of {@link android.content.Context}) <li>The {@link java.lang.Class} of the app component to which the system should deliver the {@link android.content.Intent} (in this case, the activity that should be started) </ul> <div class="sidebox-wrapper"> <div class="sidebox"> <h3>Sending an intent to other apps</h3> <p>The intent created in this lesson is what's considered an <em>explicit intent</em>, because the {@link android.content.Intent} specifies the exact app component to which the intent should be given. However, intents can also be <em>implicit</em>, in which case the {@link android.content.Intent} does not specify the desired component, but allows any app installed on the device to respond to the intent as long as it satisfies the meta-data specifications for the action that's specified in various {@link android.content.Intent} parameters. For more information, see the class about <a href="{@docRoot}training/basics/intents/index.html">Interacting with Other Apps</a>.</p> </div> </div> <p class="note"><strong>Note:</strong> The reference to {@code DisplayMessageActivity} will raise an error if you’re using an IDE such as Eclipse because the class doesn’t exist yet. Ignore the error for now; you’ll create the class soon.</p> <p>An intent not only allows you to start another activity, but it can carry a bundle of data to the activity as well. Inside the {@code sendMessage()} method, use {@link android.app.Activity#findViewById findViewById()} to get the {@link android.widget.EditText} element and add its text value to the intent:</p> <pre> Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.edit_message); String message = editText.getText().toString(); intent.putExtra(EXTRA_MESSAGE, message); </pre> <p class="note"><strong>Note:</strong> You now need an import statement for <code>android.widget.EditText</code>. You'll define the <code>EXTRA_MESSAGE</code> constant in a moment.</p> <p>An {@link android.content.Intent} can carry a collection of various data types as key-value pairs called <em>extras</em>. The {@link android.content.Intent#putExtra putExtra()} method takes the key name in the first parameter and the value in the second parameter.</p> <p>In order for the next activity to query the extra data, you should define the key for your intent's extra using a public constant. So add the {@code EXTRA_MESSAGE} definition to the top of the {@code MainActivity} class:</p> <pre> public class MainActivity extends ActionBarActivity { public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"; ... } </pre> <p>It's generally a good practice to define keys for intent extras using your app's package name as a prefix. This ensures they are unique, in case your app interacts with other apps.</p> <h2 id="StartActivity">Start the Second Activity</h2> <p>To start an activity, call {@link android.app.Activity#startActivity startActivity()} and pass it your {@link android.content.Intent}. The system receives this call and starts an instance of the {@link android.app.Activity} specified by the {@link android.content.Intent}.</p> <p>With this new code, the complete {@code sendMessage()} method that's invoked by the Send button now looks like this:</p> <pre> /** Called when the user clicks the Send button */ public void sendMessage(View view) { Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.edit_message); String message = editText.getText().toString(); intent.putExtra(EXTRA_MESSAGE, message); startActivity(intent); } </pre> <p>Now you need to create the {@code DisplayMessageActivity} class in order for this to work.</p> <h2 id="CreateActivity">Create the Second Activity</h2> <div class="figure" style="width:400px"> <img src="{@docRoot}images/training/firstapp/adt-new-activity.png" alt="" /> <p class="img-caption"><strong>Figure 1.</strong> The new activity wizard in Eclipse.</p> </div> <p>To create a new activity using Eclipse:</p> <ol> <li>Click <strong>New</strong> <img src="{@docRoot}images/tools/eclipse-new.png" style="vertical-align:baseline;margin:0" /> in the toolbar.</li> <li>In the window that appears, open the <strong>Android</strong> folder and select <strong>Android Activity</strong>. Click <strong>Next</strong>.</li> <li>Select <strong>BlankActivity</strong> and click <strong>Next</strong>.</li> <li>Fill in the activity details: <ul> <li><strong>Project</strong>: MyFirstApp</li> <li><strong>Activity Name</strong>: DisplayMessageActivity</li> <li><strong>Layout Name</strong>: activity_display_message</li> <li><strong>Fragment Layout Name</strong>: fragment_display_message</li> <li><strong>Title</strong>: My Message</li> <li><strong>Hierarchial Parent</strong>: com.example.myfirstapp.MainActivity</li> <li><strong>Navigation Type</strong>: None</li> </ul> <p>Click <strong>Finish</strong>.</p> </li> </ol> <p>If you're using a different IDE or the command line tools, create a new file named {@code DisplayMessageActivity.java} in the project's <code>src/</code> directory, next to the original {@code MainActivity.java} file.</p> <p>Open the {@code DisplayMessageActivity.java} file. If you used Eclipse to create this activity:</p> <ul> <li>The class already includes an implementation of the required {@link android.app.Activity#onCreate onCreate()} method. You will update the implementation of this method later.</li> <li>There's also an implementation of the {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} method, but you won't need it for this app so you can remove it.</li> <li>There's also an implementation of {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} which handles the behavior for the action bar's <em>Up</em> behavior. Keep this one the way it is.</li> <li>There's also a <code>PlaceholderFragment</code> class that extends {@link android.app.Fragment}. You will not need this class in the final version of this activity.</li> </ul> <p>Fragments decompose application functionality and UI into reusable modules. For more information on fragments, see the <a href="{@docRoot}guide/components/fragments.html">Fragments API Guide</a>. The final version of this activity does not use fragments.</p> <p class="note"><strong>Note:</strong> Your activity may look different if you did not use the latest version of the ADT plugin. Make sure you install the latest version of the <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT plugin</a> to complete this tutorial.</p> <p>The {@code DisplayMessageActivity} class should now look like this:</p> <pre> public class DisplayMessageActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_display_message); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()).commit(); } } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } /** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_display_message, container, false); return rootView; } } } </pre> <p>If you used an IDE other than Eclipse, update your {@code DisplayMessageActivity} class with the above code.</p> <p>All subclasses of {@link android.app.Activity} must implement the {@link android.app.Activity#onCreate onCreate()} method. The system calls this when creating a new instance of the activity. This method is where you must define the activity layout with the {@link android.app.Activity#setContentView setContentView()} method and is where you should perform initial setup for the activity components.</p> <p class="note"><strong>Note:</strong> If you are using an IDE other than Eclipse, your project does not contain the {@code activity_display_message} layout that's requested by {@link android.app.Activity#setContentView setContentView()}. That's OK because you will update this method later and won't be using that layout.</p> <h3 id="AddTitle">Add the title string</h3> <p>If you used Eclipse, you can skip to the <a href="#AddToManifest">next section</a>, because the template provides the title string for the new activity.</p> <p>If you're using an IDE other than Eclipse, add the new activity's title to the {@code strings.xml} file:</p> <pre> <resources> ... <string name="title_activity_display_message">My Message</string> </resources> </pre> <h3 id="AddToManifest">Add it to the manifest</h3> <p>All activities must be declared in your manifest file, <code>AndroidManifest.xml</code>, using an <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element.</p> <p>When you use the Eclipse tools to create the activity, it creates a default entry. If you're using a different IDE, you need to add the manifest entry yourself. It should look like this:</p> <pre> <application ... > ... <activity android:name="com.example.myfirstapp.DisplayMessageActivity" android:label="@string/title_activity_display_message" android:parentActivityName="com.example.myfirstapp.MainActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.myfirstapp.MainActivity" /> </activity> </application> </pre> <p>The <a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code android:parentActivityName}</a> attribute declares the name of this activity's parent activity within the app's logical hierarchy. The system uses this value to implement default navigation behaviors, such as <a href="{@docRoot}design/patterns/navigation.html">Up navigation</a> on Android 4.1 (API level 16) and higher. You can provide the same navigation behaviors for older versions of Android by using the <a href="{@docRoot}tools/support-library/index.html">Support Library</a> and adding the <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> element as shown here.</p> <p class="note"><strong>Note:</strong> Your Android SDK should already include the latest Android Support Library. It's included with the ADT Bundle but if you're using a different IDE, you should have installed it during the <a href="{@docRoot}sdk/installing/adding-packages.html">Adding Platforms and Packages</a> step. When using the templates in Eclipse, the Support Library is automatically added to your app project (you can see the library's JAR file listed under <em>Android Dependencies</em>). If you're not using Eclipse, you need to manually add the library to your project—follow the guide for <a href="{@docRoot}tools/support-library/setup.html">setting up the Support Library</a> then return here.</p> <p>If you're developing with Eclipse, you can run the app now, but not much happens. Clicking the Send button starts the second activity but it uses a default "Hello world" layout provided by the template. You'll soon update the activity to instead display a custom text view, so if you're using a different IDE, don't worry that the app won't yet compile.</p> <h2 id="ReceiveIntent">Receive the Intent</h2> <p>Every {@link android.app.Activity} is invoked by an {@link android.content.Intent}, regardless of how the user navigated there. You can get the {@link android.content.Intent} that started your activity by calling {@link android.app.Activity#getIntent()} and retrieve the data contained within it.</p> <p>In the {@code DisplayMessageActivity} class’s {@link android.app.Activity#onCreate onCreate()} method, get the intent and extract the message delivered by {@code MainActivity}:</p> <pre> Intent intent = getIntent(); String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); </pre> <h2 id="DisplayMessage">Display the Message</h2> <p>To show the message on the screen, create a {@link android.widget.TextView} widget and set the text using {@link android.widget.TextView#setText setText()}. Then add the {@link android.widget.TextView} as the root view of the activity’s layout by passing it to {@link android.app.Activity#setContentView setContentView()}.</p> <p>The complete {@link android.app.Activity#onCreate onCreate()} method for {@code DisplayMessageActivity} now looks like this:</p> <pre> @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get the message from the intent Intent intent = getIntent(); String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); // Create the text view TextView textView = new TextView(this); textView.setTextSize(40); textView.setText(message); // Set the text view as the activity layout setContentView(textView); } </pre> <p>You can now run the app. When it opens, type a message in the text field, click Send, and the message appears on the second activity.</p> <img src="{@docRoot}images/training/firstapp/firstapp.png" /> <p class="img-caption"><strong>Figure 2.</strong> Both activities in the final app, running on Android 4.4. <p>That's it, you've built your first Android app!</p> <p>To learn more, follow the link below to the next class.</p>