The chapter entitled An Android Intents Overview covered the theory of using intents to launch activities. This chapter will put that theory into practice by creating an example application.
The example Android Studio application project created in this chapter will demonstrate the use of an explicit intent to launch an activity, including the transfer of data between sending and receiving activities. The next chapter (An Android Implicit Intent Tutorial) will demonstrate using implicit intents.
Creating the Explicit Intent Example Application
Select the New Project option from the welcome screen and, within the resulting new project dialog, choose the Empty Views Activity template before clicking on the Next button.
Enter ExplicitIntent into the Name field and specify com.ebookfrenzy.explicitintent as the package name. Before clicking on the Finish button, change the Minimum API level setting to API 26: Android 8.0 (Oreo) and the Language menu to Kotlin. Using the steps outlined in section 18.8 Migrating a Project to View Binding, convert the project to use view binding.
Designing the User Interface Layout for MainActivity
The user interface for MainActivity will consist of a ConstraintLayout view containing EditText (Plain Text), TextView, and Button views named editText1, textView1, and button1, respectively. Using the Project tool window, locate the activity_main.xml resource file for MainActivity (under app -> res -> layout) and double-click on it to load it into the Android Studio Layout Editor tool. Select the default “Hello World!” TextView and use the Attributes tool window to assign an ID of textView1.
Drag a Button object from the palette and position it to be horizontally centered and located beneath the bottom edge of the TextView. Change the text property to read “Send Text” and configure the onClick property to call a method named sendText.
Next, add a Plain Text object to be centered horizontally and positioned above the top edge of the TextView. Using the Attributes tool window, remove the “Name” string assigned to the text property and set the ID to editText1. With the layout completed, click on the toolbar Infer constraints button to add appropriate constraints:
Finally, click the red warning button in the top right-hand corner of the Layout Editor window and use the resulting panel to extract the “Send Text” string to a resource named send_text. Once the layout is complete, the user interface should resemble that illustrated in Figure 58-2:
Creating the Second Activity Class
When the “Send Text” button is touched by the user, an intent will be issued requesting that a second activity be launched into which the user can enter a response. The next step, therefore, is to create the second activity. Within the Project tool window, right-click on the com.ebookfrenzy.explicitintent package name located in app -> kotlin+java and select the New -> Activity -> Empty Views Activity menu option to display the New Android Activity dialog as shown in Figure 58-3:
Enter SecondActivity into the Activity Name and Title fields, name the layout file activity_second, and change the Language menu to Kotlin. Since this activity will not be started when the application is launched (it will instead be launched via an intent by MainActivity when the button is pressed), ensure the Launcher Activity option is disabled before clicking the Finish button.
Designing the User Interface Layout for SecondActivity
The elements required for the second activity’s user interface are a Plain Text EditText, TextView, and Button view. With these requirements in mind, load the activity_second.xml layout into the Layout Editor tool, and add the views.
During the design process, note that the onClick property on the button view has been configured to call a method named returnText, and the TextView and EditText views have been assigned IDs textView2 and editText2, respectively. Once completed, the layout should resemble Figure 58-4. Note that the text on the button (“Return Text”) has been extracted to a string resource named return_text.
With the layout complete, click on the Infer constraints toolbar button to add the necessary constraints to the layout:
Reviewing the Application Manifest File
For MainActivity to be able to launch SecondActivity using an intent, an entry for SecondActivity needs to be present in the AndroidManifest.xml file. Locate this file within the Project tool window (app -> manifests), double-click on it to load it into the editor, and verify that Android Studio has automatically added an entry for the activity:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ExplicitIntent"
tools:targetApi="31">
<activity
android:name=".SecondActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Code language: HTML, XML (xml)
With the second activity created and listed in the manifest file, it is time to write some code in the MainActivity class to issue the intent.
Creating the Intent
The objective for MainActivity is to create and start an intent when the user touches the “Send Text” button. As part of the intent creation process, the question string entered by the user into the EditText view will be added to the intent object as a key-value pair. When the user interface layout was created for MainActivity, the button object was configured to call a method named sendText() when “clicked” by the user. This method now needs to be added to the MainActivity class MainActivity.kt source file as follows:
package com.ebookfrenzy.explicitintent
.
.
import android.view.View
import android.content.Intent
class MainActivity : AppCompatActivity() {
.
.
fun sendText(view: View) {
val i = Intent(this, SecondActivity::class.java)
val myString = binding.editText1.text.toString()
i.putExtra("qString", myString)
startActivity(i)
}
}
Code language: Kotlin (kotlin)
The code for the sendText() method follows the techniques outlined in An Android Intents Overview. First, a new Intent instance is created, passing through the current activity and the class name of SecondActivity as arguments. Next, the text entered into the EditText object is added to the intent object as a key-value pair, and the intent started via a call to startActivity(), passing through the intent object as an argument.
Compile and run the application and touch the “Send Text” button to launch SecondActivity. Return to the MainActivity screen using either the back button (located in the toolbar along the bottom of the display) or by swiping right from the edge of the screen on newer Android versions.
Extracting Intent Data
Now that SecondActivity is being launched from MainActivity, the next step is to extract the String data value included in the intent and assign it to the TextView object in the SecondActivity user interface. This involves adding some code to the onCreate() method of SecondActivity in the SecondActivity.kt source file in addition to adapting the activity to use view binding:
package com.ebookfrenzy.explicitintent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.content.Intent
import com.ebookfrenzy.explicitintent.databinding.ActivitySecondBinding
class SecondActivity : AppCompatActivity() {
private lateinit var binding: ActivitySecondBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.second_activity)
binding = ActivitySecondBinding.inflate(layoutInflater)
setContentView(binding.root)
val extras = intent.extras ?: return
val qString = extras.getString("qString")
binding.textView2.text = qString
}
}
Code language: Kotlin (kotlin)
Compile and run the application either within an emulator or on a physical Android device. Enter some text into the text box in MainActivity before touching the “Send Text” button. The message should now appear on the TextView component in the SecondActivity user interface.
Launching SecondActivity as a Sub-Activity
For SecondActivity to be able to return data to MainActivity, SecondActivity must be started as a sub-activity of MainActivity. This means we need to call registerForActivityResult() and declare a callback handler to be called when SecondActivity returns. This callback will extract the data returned by SecondActivty and display it on textView1.
The call to registerForActivityResult() returns an ActivtyResultLauncher instance which can be called from within sendText() to launch the intent. Edit the MainActivity.kt file so that it reads as follows:
.
.
import android.app.Activity
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
.
.
class MainActivity : AppCompatActivity() {
.
.
val startForResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()) {
result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
val data = result.data
data?.let {
if (it.hasExtra("returnData")) {
val returnString = it.extras?.getString("returnData")
binding.textView1.text = returnString
}
}
}
}
fun sendText(view: View) {
val i = Intent(this, SecondActivity::class.java)
val myString = binding.editText1.text.toString()
i.putExtra("qString", myString)
startActivity(i)
startForResult.launch(i)
}
}
.
.
Code language: Kotlin (kotlin)
Returning Data from a Sub-Activity
SecondActivity is now launched as a sub-activity of MainActivity, which has, in turn, been modified to handle data returned from SecondActivity. All that remains is to modify SecondActivity.kt to implement the finish() method and to add a method named returnText(). The finish() method is triggered when an activity exits (for example, when the user selects the back button on the device):
fun returnText(view: View) {
finish()
}
override fun finish() {
val data = Intent()
val returnString = binding.editText2.text.toString()
data.putExtra("returnData", returnString)
setResult(RESULT_OK, data)
super.finish()
}
Code language: Kotlin (kotlin)
The finish() method creates a new intent, adds the return data as a key-value pair, and then calls the setResult() method, passing through a result code and the intent object. The returnText() method calls the finish() method.
Open the activity_second.xml file, select the button widget, and configure the onClick attribute to call the returnText() method.
Testing the Application
Compile and run the application, enter a question into the text field on MainActivity, and touch the “Send Text” button. When SecondActivity appears, enter the text to the EditText view and use either the back button or the “Return Text” button to return to MainActivity where the response should appear in the text view object.
Summary
Having covered the basics of intents in the previous chapter, the goal of this chapter was to work through the creation of an application project in Android Studio designed to demonstrate the use of explicit intents together with the concepts of data transfer between a parent activity and sub-activity.
The next chapter will use an example to demonstrate implicit intents in action.