Home | History | Annotate | Download | only in firstapp
      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 &lt;Button>} element:</p>
     52 
     53 <pre>
     54 &lt;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 &#64;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     &#64;SuppressLint("NewApi")
    265     &#64;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     &#64;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 &lt;resources>
    315     ...
    316     &lt;string name="title_activity_display_message">My Message&lt;/string>
    317 &lt;/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 &lt;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 &lt;application ... >
    334     ...
    335     &lt;activity
    336         android:name="com.example.myfirstapp.DisplayMessageActivity"
    337         android:label="@string/title_activity_display_message"
    338         android:parentActivityName="com.example.myfirstapp.MainActivity" >
    339         &lt;meta-data
    340             android:name="android.support.PARENT_ACTIVITY"
    341             android:value="com.example.myfirstapp.MainActivity" />
    342     &lt;/activity>
    343 &lt;/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 &lt;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&mdash;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 &#64;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