1. Welcome
Introduction
An Activity
represents a single screen in your app with which your user can perform a single, focused task such as taking a photo, sending an email, or viewing a map. An activity is usually presented to the user as a full-screen window.
An app usually consists of multiple screens that are loosely bound to each other. Each screen is an activity. Typically, one activity in an app is specified as the "main" activity (MainActivity.java
), which is presented to the user when the app is launched. The main activity can then start other activities to perform different actions.
Each time a new activity starts, the previous activity is stopped, but the system preserves the activity in a stack (the "back stack"). When a new activity starts, that new activity is pushed onto the back stack and takes user focus. The back stack follows basic "last in, first out" stack logic. When the user is done with the current activity and presses the Back button, that activity is popped from the stack and destroyed, and the previous activity resumes.
An activity is started or activated with an intent. An Intent
is an asynchronous message that you can use in your activity to request an action from another activity, or from some other app component. You use an intent to start one activity from another activity, and to pass data between activities.
An Intent
can be explicit or implicit:
- An explicit intent is one in which you know the target of that intent. That is, you already know the fully qualified class name of that specific activity.
- An implicit intent is one in which you do not have the name of the target component, but you have a general action to perform.
In this practical you create explicit intents. You find out how to use implicit intents in a later practical.
What you should already know
You should be able to:
- Create and run apps in Android Studio.
- Use the layout editor to create a layout within a
ConstraintLayout
- Edit the layout XML code.
- Add
onClick
functionality to aButton
.
What you'll learn
- How to create a new
Activity
in Android Studio. - How to define parent and child activities for Up navigation.
- How to start an
Activity
with an explicitIntent
. - How to pass data between each
Activity
with an explicitIntent
.
What you'll do
- Create a new Android app with a main
Activity
and a secondActivity
. - Pass some data (a string) from the main
Activity
to the second using anIntent
, and display that data in the secondActivity
. - Send a second different bit of data back to the main
Activity
, also using anIntent
.
2. App overview
In this chapter you create and build an app called Two Activities that, unsurprisingly, contains two Activity
implementations. You build the app in three stages.
In the first stage, you create an app whose main activity contains one button, Send. When the user clicks this button, your main activity uses an intent to start the second activity.
In the second stage, you add an EditText
view to the main activity. The user enters a message and clicks Send. The main activity uses an intent to start the second activity and send the user's message to the second activity. The second activity displays the message it received.
In the final stage of creating the Two Activities app, you add an EditText
and a Reply button to the second activity. The user can now type a reply message and tap Reply, and the reply is displayed on the main activity. At this point, you use an intent to pass the reply back from the second activity to the main activity.
3. Task 1: Create the TwoActivities project
In this task you set up the initial project with a main Activity
, define the layout, and define a skeleton method for the onClick
button event.
1.1 Create the TwoActivities project
- Start Android Studio and create a new Android Studio project.
Name your app Two Activities and choose the same Phone and Tablet settings that you used in previous practicals. The project folder is automatically named TwoActivities
, and the app name that appears in the app bar will be "Two Activities".
- Choose Empty Activity for the
Activity
template. Click Next. - Accept the default
Activity
name (MainActivity
). Make sure the Generate Layout file and Backwards Compatibility (AppCompat) options are checked. - Click Finish.
1.2 Define the layout for the main Activity
- Open res > layout > activity_main.xml in the Project > Android pane. The layout editor appears.
- Click the Design tab if it is not already selected, and delete the
TextView
(the one that says "Hello World") in the Component Tree pane. - With Autoconnect turned on (the default setting), drag a
Button
from the Palette pane to the lower right corner of the layout. Autoconnect creates constraints for theButton
. - In the Attributes pane, set the ID to button_main, the layout_width and layout_height to wrap_content, and enter Send for the Text field. The layout should now look like this:
- Click the Text tab to edit the XML code. Add the following attribute to the
Button
:
android:onClick="launchSecondActivity"
The attribute value is underlined in red because the launchSecondActivity()
method has not yet been created. Ignore this error for now; you fix it in the next task.
- Extract the string resource, as described in a previous practical, for "Send" and use the name
button_main
for the resource.
The XML code for the Button
should look like the following:
<Button
android:id="@+id/button_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:text="@string/button_main"
android:onClick="launchSecondActivity"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
1.3 Define the Button action
In this task you implement the launchSecondActivity()
method you referred to in the layout for the android:onClick
attribute.
- Click on
"launchSecondActivity"
in theactivity_main.xml
XML code. - Press
Alt+Enter
(Option+Enter
on a Mac) and select Create ‘launchSecondActivity(View)' in ‘MainActivity.
The MainActivity
file opens, and Android Studio generates a skeleton method for the launchSecondActivity
() handler.
- Inside
launchSecondActivity()
, add aLog
statement that says "Button Clicked!"
Log.d(LOG_TAG, "Button clicked!");
LOG_TAG
will show as red. You add the definition for that variable in a later step.
- At the top of the
MainActivity
class, add a constant for theLOG_TAG
variable:
private static final String LOG_TAG =
MainActivity.class.getSimpleName();
This constant uses the name of the class itself as the tag.
- Run your app. When you click the Send button you see the "Button Clicked!" message in the Logcat pane. If there's too much output in the monitor, type MainActivity into the search box, and the Logcat pane will only show lines that match that tag.
The code for MainActivity
should look as follows:
package com.example.android.twoactivities;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG =
MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void launchSecondActivity(View view) {
Log.d(LOG_TAG, "Button clicked!");
}
}
4. Task 2: Create and launch the second Activity
Each new activity you add to your project has its own layout and Java files, separate from those of the main activity. They also have their own <activity>
elements in the AndroidManifest.xml
file. As with the main activity, new activity implementations that you create in Android Studio also extend from the AppCompatActivity
class.
Each activity in your app is only loosely connected with other activities. However, you can define an activity as a parent of another activity in the AndroidManifest.xml
file. This parent-child relationship enables Android to add navigation hints such as left-facing arrows in the title bar for each activity.
An activity communicates with other activities (in the same app and across different apps) with an intent. An Intent
can be explicit or implicit:
- An explicit intent is one in which you know the target of that intent; that is, you already know the fully qualified class name of that specific activity.
- An implicit intent is one in which you do not have the name of the target component, but have a general action to perform.
In this task you add a second activity to our app, with its own layout. You modify the AndroidManifest.xml
file to define the main activity as the parent of the second activity. Then you modify the launchSecondActivity()
method in MainActivity
to include an intent that launches the second activity when you click the button.
2.1 Create the second Activity
- Click the app folder for your project and choose File > New > Activity > Empty Activity.
- Name the new
Activity
SecondActivity. Make sure Generate Layout File and Backwards Compatibility (AppCompat) are checked. The layout name is filled in asactivity_second
. Do not check the Launcher Activity option. - Click Finish. Android Studio adds both a new
Activity
layout (activity_second.xml
) and a new Java file (SecondActivity.java
) to your project for the newActivity
. It also updates theAndroidManifest.xml
file to include the newActivity
.
2.2 Modify the AndroidManifest.xml file
- Open manifests > AndroidManifest.xml.
- Find the
<activity>
element that Android Studio created for the secondActivity
.
<activity android:name=".SecondActivity"></activity>
- Replace the entire
<activity>
element with the following:
<activity android:name=".SecondActivity"
android:label = "Second Activity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=
"com.example.android.twoactivities.MainActivity" />
</activity>
The label
attribute adds the title of the Activity
to the app bar.
With the parentActivityName
attribute, you indicate that the main activity is the parent of the second activity. This relationship is used for Up navigation in your app: the app bar for the second activity will have a left-facing arrow so the user can navigate "upward" to the main activity.
With the <meta-data>
element, you provide additional arbitrary information about the activity in the form of key-value pairs. In this case the metadata attributes do the same thing as the android:parentActivityName
attribute—they define a relationship between two activities for upward navigation. These metadata attributes are required for older versions of Android, because the android:parentActivityName
attribute is only available for API levels 16 and higher.
- Extract a string resource for "Second Activity" in the code above, and use
activity2_name
as the resource name.
2.3 Define the layout for the second Activity
- Open activity_second.xml and click the Design tab if it is not already selected.
- Drag a TextView from the Palette pane to the top left corner of the layout, and add constraints to the top and left sides of the layout. Set its attributes in the Attributes pane as follows:
Attribute | Value |
|
|
Top margin |
|
Left margin |
|
|
|
|
|
|
|
|
|
|
|
The value of textAppearance is a special Android theme attribute that defines basic font styles. You learn more about themes in a later lesson.
The layout should now look like this:
- Click the Text tab to edit the XML code, and extract the "Message Received" string into a resource named
text_header
. - Add the
android:layout_marginLeft="8dp"
attribute to theTextView
to complement thelayout_marginStart
attribute for older versions of Android.
The XML code for activity_second.xml
should be as follows:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.twoactivities.SecondActivity">
<TextView
android:id="@+id/text_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
android:text="@string/text_header"
android:textAppearance=
"@style/TextAppearance.AppCompat.Medium"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
2.4 Add an Intent to the main Activity
In this task you add an explicit Intent
to the main Activity
. This Intent
is used to activate the second Activity
when the Send button is clicked.
- Open MainActivity.
- Create a new
Intent
in thelaunchSecondActivity()
method.
The Intent constructor takes two arguments for an explicit Intent
: an application Context
and the specific component that will receive that Intent
. Here you should use this
as the Context
, and SecondActivity.class
as the specific class:
Intent intent = new Intent(this, SecondActivity.class);
- Call the
startActivity()
method with the newIntent
as the argument.
startActivity(intent);
- Run the app.
When you click the Send button, MainActivity
sends the Intent
and the Android system launches SecondActivity
, which appears on the screen. To return to MainActivity
, click the Up button (the left arrow in the app bar) or the Back button at the bottom of the screen.
5. Task 3: Send data from the main Activity to the second Activity
In the last task, you added an explicit intent to MainActivity
that launched SecondActivity
. You can also use an intent to send data from one activity to another while launching it.
Your intent object can pass data to the target activity in two ways: in the data field, or in the intent extras. The intent data is a URI indicating the specific data to be acted on. If the information you want to pass to an activity through an intent is not a URI, or you have more than one piece of information you want to send, you can put that additional information into the extras instead.
The intent extras are key/value pairs in a Bundle
. A Bundle
is a collection of data, stored as key/value pairs. To pass information from one activity to another, you put keys and values into the intent extra Bundle
from the sending activity, and then get them back out again in the receiving activity.
In this task, you modify the explicit intent in MainActivity
to include additional data (in this case, a user-entered string) in the intent extra Bundle
. You then modify SecondActivity
to get that data back out of the intent extra Bundle
and display it on the screen.
3.1 Add an EditText to the MainActivity layout
- Open activity_main.xml.
- Drag a Plain Text (
EditText
) element from the Palette pane to the bottom of the layout, and add constraints to the left side of the layout, the bottom of the layout, and the left side of the SendButton
. Set its attributes in the Attributes pane as follows:
Attribute | Value |
|
|
Right margin |
|
Left margin |
|
Bottom margin |
|
|
|
|
|
|
|
|
|
| (Delete any text in this field) |
The new layout in activity_main.xml
looks like this:
- Click the Text tab to edit the XML code, and extract the "Enter Your Message Here" string into a resource named
editText_main
.
The XML code for the layout should look something like the following.
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.twoactivities.MainActivity">
<Button
android:id="@+id/button_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:text="@string/button_main"
android:onClick="launchSecondActivity"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<EditText
android:id="@+id/editText_main"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:ems="10"
android:hint="@string/editText_main"
android:inputType="textLongMessage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/button_main"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
3.2 Add a string to the Intent extras
The Intent
extras are key/value pairs in a Bundle
. A Bundle
is a collection of data, stored as key/value pairs. To pass information from one Activity
to another, you put keys and values into the Intent
extra Bundle
from the sending Activity
, and then get them back out again in the receiving Activity
.
- Open MainActivity.
- Add a
public
constant at the top of the class to define the key for theIntent
extra:
public static final String EXTRA_MESSAGE =
"com.example.android.twoactivities.extra.MESSAGE";
- Add a private variable at the top of the class to hold the
EditText
:
private EditText mMessageEditText;
- In the
onCreate()
method, usefindViewById()
to get a reference to theEditText
and assign it to that private variable:
mMessageEditText = findViewById(R.id.editText_main);
- In the
launchSecondActivity()
method, just under the newIntent
, get the text from theEditText
as a string:
String message = mMessageEditText.getText().toString();
- Add that string to the
Intent
as an extra with theEXTRA_MESSAGE
constant as the key and the string as the value:
intent.putExtra(EXTRA_MESSAGE, message);
The onCreate()
method in MainActivity
should now look like the following:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMessageEditText = findViewById(R.id.editText_main);
}
The launchSecondActivity()
method in MainActivity
should now look like the following:
public void launchSecondActivity(View view) {
Log.d(LOG_TAG, "Button clicked!");
Intent intent = new Intent(this, SecondActivity.class);
String message = mMessageEditText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
3.3 Add a TextView to SecondActivity for the message
- Open activity_second.xml.
- Drag another TextView to the layout underneath the
text_header
TextView
, and add constraints to the left side of the layout and to the bottom oftext_header
. - Set the new
TextView
attributes in the Attributes pane as follows:
Attribute | Value |
|
|
Top margin |
|
Left margin |
|
|
|
|
|
| (Delete any text in this field) |
|
|
The new layout looks the same as it did in the previous task, because the new TextView
does not (yet) contain any text, and thus does not appear on the screen.
The XML code for the activity_second.xml
layout should look something like the following:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.twoactivities.SecondActivity">
<TextView
android:id="@+id/text_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:text="@string/text_header"
android:textAppearance=
"@style/TextAppearance.AppCompat.Medium"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_header" />
</android.support.constraint.ConstraintLayout>
3.4 Modify SecondActivity to get the extras and display the message
- Open SecondActivity to add code to the
onCreate()
method. - Get the
Intent
that activated thisActivity
:
Intent intent = getIntent();
- Get the string containing the message from the
Intent
extras using theMainActivity.EXTRA_MESSAGE
static variable as the key:
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
- Use
findViewByID()
to get a reference to theTextView
for the message from the layout:
TextView textView = findViewById(R.id.text_message);
- Set the text of the
TextView
to the string from theIntent
extra:
textView.setText(message);
- Run the app. When you type a message in
MainActivity
and click Send,SecondActivity
launches and displays the message.
The SecondActivity
onCreate()
method should look as follows:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = findViewById(R.id.text_message);
textView.setText(message);
}
6. Task 4: Return data back to the main Activity
Now that you have an app that launches a new activity and sends data to it, the final step is to return data from the second activity back to the main activity. You also use an intent and intent extras for this task.
4.1 Add an EditText and a Button to the SecondActivity layout
- Open strings.xml and add string resources for the
Button
text and the hint for theEditText
that you will add toSecondActivity
:
<string name="button_second">Reply</string>
<string name="editText_second">Enter Your Reply Here</string>
- Open activity_main.xml and activity_second.xml.
- Copy the
EditText
andButton
from theactivity_main.xml
layout file and Paste them into theactivity_second.xml
layout. - In
activity_second.xml
, modify the attribute values for theButton
as follows:
Old attribute value | New attribute value |
|
|
|
|
|
|
- In
activity_second.xml
, modify the attribute values for theEditText
as follows:
Old attribute value | New attribute value |
|
|
|
|
|
|
- In the XML layout editor, click on returnReply, press
Alt+Enter
(Option+Return
on a Mac), and select Create ‘returnReply(View)' in ‘SecondActivity'.
Android Studio generates a skeleton method for the returnReply()
handler. You implement this method in the next task.
The new layout for activity_second.xml
looks like this:
The XML code for the activity_second.xml
layout file is as follows:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.twoactivities.SecondActivity">
<TextView
android:id="@+id/text_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
android:text="@string/text_header"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_header" />
<Button
android:id="@+id/button_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:text="@string/button_second"
android:onClick="returnReply"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<EditText
android:id="@+id/editText_second"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:ems="10"
android:hint="@string/editText_second"
android:inputType="textLongMessage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/button_second"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
4.2 Create a response Intent in the second Activity
The response data from the second Activity
back to the main Activity
is sent in an Intent
extra. You construct this return Intent
and put the data into it in much the same way you do for the sending Intent
.
- Open SecondActivity.
- At the top of the class, add a public constant to define the key for the
Intent
extra:
public static final String EXTRA_REPLY =
"com.example.android.twoactivities.extra.REPLY";
- Add a private variable at the top of the class to hold the
EditText
.
private EditText mReply;
- In the
onCreate()
method, before theIntent
code, usefindViewByID()
to get a reference to theEditText
and assign it to that private variable:
mReply = findViewById(R.id.editText_second);
- In the
returnReply()
method, get the text of theEditText
as a string:
String reply = mReply.getText().toString();
- In the
returnReply()
method, create a new intent for the response—don't reuse theIntent
object that you received from the original request.
Intent replyIntent = new Intent();
- Add the
reply
string from theEditText
to the new intent as anIntent
extra. Because extras are key/value pairs, here the key isEXTRA_REPLY
, and the value is thereply
:
replyIntent.putExtra(EXTRA_REPLY, reply);
- Set the result to
RESULT_OK
to indicate that the response was successful. TheActivity
class defines the result codes, includingRESULT_OK
andRESULT_CANCELLED
.
setResult(RESULT_OK,replyIntent);
- Call
finish()
to close theActivity
and return toMainActivity
.
finish();
The code for SecondActivity
should now be as follows:
public class SecondActivity extends AppCompatActivity {
public static final String EXTRA_REPLY =
"com.example.android.twoactivities.extra.REPLY";
private EditText mReply;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mReply = findViewById(R.id.editText_second);
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = findViewById(R.id.text_message);
textView.setText(message);
}
public void returnReply(View view) {
String reply = mReply.getText().toString();
Intent replyIntent = new Intent();
replyIntent.putExtra(EXTRA_REPLY, reply);
setResult(RESULT_OK, replyIntent);
finish();
}
}
4.3 Add TextView elements to display the reply
MainActivity
needs a way to display the reply that SecondActivity
sends. In this task you add TextView
elements to the activity_main.xml
layout to display the reply in MainActivity
.
To make this task easier, you copy the TextView
elements you used in SecondActivity
.
- Open strings.xml and add a string resource for the reply header:
<string name="text_header_reply">Reply Received</string>
- Open activity_main.xml and activity_second.xml.
- Copy the two
TextView
elements from theactivity_second.xml
layout file and paste them into theactivity_main.xml
layout above theButton
. - In
activity_main.xml
, modify the attribute values for the firstTextView
as follows:
Old attribute value | New attribute value |
|
|
|
|
- In
activity_main.xml
, modify the attribute values for the secondTextView
a follows:
Old attribute value | New attribute value |
|
|
|
|
- Add the
android:visibility
attribute to eachTextView
to make them initially invisible. (Having them visible on the screen, but without any content, can be confusing to the user.)
android:visibility="invisible"
You will make these TextView
elements visible after the response data is passed back from the second Activity
.
The activity_main.xml
layout looks the same as it did in the previous task—although you have added two new TextView
elements to the layout. Because you set these elements to invisible, they do not appear on the screen.
The following is the XML code for the activity_main.xml
file:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.twoactivities.MainActivity">
<TextView
android:id="@+id/text_header_reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
android:text="@string/text_header_reply"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textStyle="bold"
android:visibility="invisible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_message_reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:visibility="invisible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_header_reply" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:text="@string/button_main"
android:onClick="launchSecondActivity"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<EditText
android:id="@+id/editText_main"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:ems="10"
android:hint="@string/editText_main"
android:inputType="textLongMessage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/button2"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
4.4 Get the reply from the Intent extra and display it
When you use an explicit Intent
to start another Activity
, you may not expect to get any data back—you're just activating that Activity
. In that case, you use startActivity()
to start the new Activity
, as you did earlier in this practical. If you want to get data back from the activated Activity
, however, you need to start it with startActivityForResult()
.
In this task you modify the app to start SecondActivity
expecting a result, to extract that return data from the Intent
, and to display that data in the TextView
elements you created in the last task.
- Open MainActivity.
- Add a public constant at the top of the class to define the key for a particular type of response you're interested in:
public static final int TEXT_REQUEST = 1;
- Add two private variables to hold the reply header and reply
TextView
elements:
private TextView mReplyHeadTextView;
private TextView mReplyTextView;
- In the
onCreate()
method, usefindViewByID()
to get references from the layout to the reply header and replyTextView
elements. Assign those view instances to the private variables:
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
The full onCreate()
method should now look like this:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMessageEditText = findViewById(R.id.editText_main);
mReplyHeadTextView = findViewById(R.id.text_header_reply);
mReplyTextView = findViewById(R.id.text_message_reply);
}
- In the
launchSecondActivity()
method, change the call tostartActivity(
) to bestartActivityForResult()
, and include theTEXT_REQUEST
key as an argument:
startActivityForResult(intent, TEXT_REQUEST);
- Override the
onActivityResult()
callback method with this signature:
@Override
public void onActivityResult(int requestCode,
int resultCode, Intent data) {
}
The three arguments to onActivityResult()
contain all the information you need to handle the return data: the requestCode
you set when you launched the Activity
with startActivityForResult()
, the resultCode
set in the launched Activity
(usually one of RESULT_OK
or RESULT_CANCELED
), and the Intent data
that contains the data returned from the launch Activity
.
- Inside
onActivityResult()
, callsuper.onActivityResult()
:
super.onActivityResult(requestCode, resultCode, data);
- Add code to test for
TEXT_REQUEST
to make sure you process the rightIntent
result, in case there are several. Also test forRESULT_OK
, to make sure that the request was successful:
if (requestCode == TEXT_REQUEST) {
if (resultCode == RESULT_OK) {
}
}
The Activity
class defines the result codes. The code can be RESULT_OK
(the request was successful), RESULT_CANCELED
(the user cancelled the operation), or RESULT_FIRST_USER
(for defining your own result codes).
- Inside the inner if block, get the
Intent
extra from the responseIntent
(data
). Here the key for the extra is theEXTRA_REPLY
constant fromSecondActivity
:
String reply = data.getStringExtra(SecondActivity.EXTRA_REPLY);
- Set the visibility of the reply header to true:
mReplyHeadTextView.setVisibility(View.VISIBLE);
- Set the reply
TextView
text to thereply
, and set its visibility to true:
mReplyTextView.setText(reply);
mReplyTextView.setVisibility(View.VISIBLE);
The full onActivityResult()
method should now look like this:
@Override
public void onActivityResult(int requestCode,
int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TEXT_REQUEST) {
if (resultCode == RESULT_OK) {
String reply =
data.getStringExtra(SecondActivity.EXTRA_REPLY);
mReplyHeadTextView.setVisibility(View.VISIBLE);
mReplyTextView.setText(reply);
mReplyTextView.setVisibility(View.VISIBLE);
}
}
}
- Run the app.
Now, when you send a message to the second Activity
and get a reply, the main Activity
updates to display the reply.
7. Solution code
Android Studio project: TwoActivities
8. Coding challenge
Challenge: Create an app with three Button
elements labeled Text One, Text Two, and Text Three. When any of these Button
elements are clicked, launch a second Activity
. That second Activity
should contain a ScrollView
that displays one of three text passages (you can include your choice of passages). Use an Intent
to launch the second Activity
with extras to indicate which of the three passages to display.
9. Summary
Overview:
- An
Activity
is an app component that provides a single screen focused on a single user task. - Each
Activity
has its own user interface layout file. - You can assign your
Activity
implementations a parent/child relationship to enable Up navigation within your app. - A
View
can be made visible or invisible with theandroid:visibility
attribute.
To implement an Activity:
- Choose File > New > Activity to start from a template and do the following steps automatically.
- If not starting from a template, create an
Activity
Java class, implement a basic UI for theActivity
in an associated XML layout file, and declare the newActivity
in AndroidManifest.xml.
Intent
:
- An
Intent
lets you request an action from another component in your app, for example, to start oneActivity
from another. AnIntent
can be explicit or implicit. - With an explicit
Intent
you indicate the specific target component to receive the data. - With an implicit
Intent
you specify the functionality you want but not the target component. - An
Intent
can include data on which to perform an action (as a URI) or additional information asIntent
extras. Intent
extras are key/value pairs in aBundle
that are sent along with theIntent
.
10. Related concept
The related concept documentation is in 2.1: Activities and intents.
11. Learn more
Android Studio documentation:
Android developer documentation:
12. Homework
This section lists possible homework assignments for students who are working through this codelab as part of a course led by an instructor. It's up to the instructor to do the following:
- Assign homework if required.
- Communicate to students how to submit homework assignments.
- Grade the homework assignments.
Instructors can use these suggestions as little or as much as they want, and should feel free to assign any other homework they feel is appropriate.
If you're working through this codelab on your own, feel free to use these homework assignments to test your knowledge.
Build and run an app
Open the HelloToast app that you created in a previous practical codelab.
- Modify the Toast button so that it launches a new
Activity
to display the word "Hello!" and the current count, as shown below. - Change the text on the
Toast
button to Say Hello.
Answer these questions
Question 1
What changes are made when you add a second Activity
to your app by choosing File > New > Activity and an Activity
template? Choose one:
- The second
Activity
is added as a Java class. You still need to add the XML layout file. - The second
Activity
XML layout file is created and a Java class added. You still need to define the class signature. - The second
Activity
is added as a Java class, the XML layout file is created, and theAndroidManifest.xml
file is changed to declare a secondActivity
. - The second
Activity
XML layout file is created, and theAndroidManifest.xml
file is changed to declare a secondActivity
.
Question 2
What happens if you remove the android:parentActivityName
and the <meta-data>
elements from the second Activity
declaration in the AndroidManifest.xml
file? Choose one:
- The second
Activity
no longer appears when you try to start it with an explicitIntent
. - The second
Activity
XML layout file is deleted. - The Back button no longer works in the second
Activity
to send the user back to the mainActivity
. - The Up button in the app bar no longer appears in the second
Activity
to send the user back to the parentActivity
.
Question 3
Which constructor method do you use to create a new explicit Intent
? Choose one:
new Intent()
new Intent(Context context, Class<?> class)
new Intent(String action, Uri uri)
new Intent(String action)
Question 4
In the HelloToast app homework, how do you add the current value of the count to the Intent
? Choose one:
- As the
Intent
data - As the
Intent
TEXT_REQUEST
- As an
Intent
action - As an
Intent
extra
Question 5
In the HelloToast app homework, how do you display the current count in the second "Hello" Activity
? Choose one:
- Get the
Intent
that theActivity
was launched with. - Get the current count value out of the
Intent
. - Update the
TextView
for the count. - All of the above.
Submit your app for grading
Guidance for graders
Check that the app has the following features:
- It displays the Say Hello button instead of the Toast button.
- The second
Activity
starts when the Say Hello button is pressed, and it displays the message "Hello!" and the current count fromMainActivity
. - The second
Activity
Java and XML layout files have been added to the project. - The XML layout file for the second
Activity
contains twoTextView
elements, one with the string "Hello!" and the second with thecount
. - It includes an implementation of a click handler method for the Say Hello button (in
MainActivity
). - It includes an implementation of the
onCreate()
method for the secondActivity
and updates the countTextView
with thecount
fromMainActivity
.
13. Next codelab
To find the next practical codelab in the Android Developer Fundamentals (V2) course, see Codelabs for Android Developer Fundamentals (V2).
For an overview of the course, including links to the concept chapters, apps, and slides, see Android Developer Fundamentals (Version 2).