© Ted Hagos 2020
T. HagosLearn Android Studio 4https://doi.org/10.1007/978-1-4842-5937-5_8

8. Intents

Ted Hagos1 
(1)
Manila, National Capital Region, Philippines
 
What we’ll cover:
  • Intent overview

  • Explicit and implicit Intents

  • Passing data between activities

  • Returning results from Intents

Android’s architecture is unique in the way it builds applications. It has this notion of components instead of just plain objects. And the way that Android makes these components interact is something that you can only find in the Android platform. Android uses Intents as a way for its components to communicate; it uses it to pass messages across components. In this chapter, we’ll look at Intents, what they are, and how we use them.

What Intents Are

An Intent is an abstract description of an operation to be performed. It’s a unique Android concept because no other platform uses the same thing as a means of component activation. In the earlier chapters, we looked at what’s inside an Android application. You might remember that an app is just a bunch of “components” (see Figure 8-1) that are loosely held together, and each component is declared in the AndroidManifest file.
../images/457413_2_En_8_Chapter/457413_2_En_8_Fig1_HTML.jpg
Figure 8-1

Logical representation of an Android App

Launching an Activity isn’t as simple as creating an instance of a particular Activity class. It’s a bit more involved than that. An Activity isn’t merely an object; it’s a component, and component activation in Android requires the use of Intents.

To launch an Activity, we need to create an Intent object, tell this Intent object what we want to activate, and then launch it. After that, the Android Runtime tries to resolve the Intent, and if successful, the target component gets activated. In code, it looks like this:
Intent intent = new Intent(context, target);
startActivity(intent);
where
  • context—Is a reference to the component that wants to initiate or launch the Intent.

  • target—Is a class object; this is the component you want to launch.

A typical scenario when launching an Activity (usually from the MainActivity) is when a user clicks a button or selects a menu item.

To try this out, you will need a project with two Activities. You already know how to create a project with an empty Activity, so just create that; presumably, the first Activity class’ name is MainActivity. To add another Activity, we can use the context menu. On the Project tool window, right-click the app folder (assuming you’re on the Android scope, which is the default), then choose NewActivityEmpty Activity, as shown in Figure 8-2.
../images/457413_2_En_8_Chapter/457413_2_En_8_Fig2_HTML.jpg
Figure 8-2

New Empty Activity

In the window that follows, type the second Activity name, as shown in Figure 8-3. Adopt the suggested layout name (or change it to your liking), and make sure it’s on the same Java package and that the source language is Java. Click Finish to proceed.
../images/457413_2_En_8_Chapter/457413_2_En_8_Fig3_HTML.jpg
Figure 8-3

New Android Activity

Next, open activity_main.xml and edit it to match Listing 8-1.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".MainActivity">
  <Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="78dp"
    android:text="Button"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Listing 8-1

app/res/layout/activity_main.xml

What I’ve done in the activity_main layout was to remove the default TextView object and replaced it with a Button View (whose id is button).

Now we can work on MainActivity. We need to attach a click handler to the Button, and on that handler, we create and launch an Intent. Listing 8-2 shows the annotated code to do that.
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button btn = findViewById(R.id.button); ❶
    btn.setOnClickListener(new View.OnClickListener() { ❷
      @Override
      public void onClick(View view) {
        Intent intent = new Intent(MainActivity.this, SecondActivity.class); ❸
        startActivity(intent); ❹
      }
    });
  }
}
Listing 8-2

MainActivity

Let’s get a reference to the Button View.

Create an OnClickListener object and bind it to the Button object.

Inside the onClick() method, let’s create an Intent object. The first parameter is a Context object, which is supposed to refer to MainActivity. I wrote MainActivity.this and not merely this because currently we’re making the call inside a click handler (which is an anonymous class); this would refer to the anonymous class’ instance and not to MainActivity. To be explicit, we refer to the context of MainActivity as MainActivity.this. Alternatively, you can also pass the Application Context as the first parameter. You can get the Application Context using the method getApplicationContext() . The second parameter is the class object of the component we want to launch, which is SecondActivity; so, we pass SecondActivity.class.

Finally, we call the startActivity() method of MainActivity, and we pass the Intent object as the parameter; this will launch the Intent.

If you run the app now, the SecondActivity will launch when you click the Button on MainActivity. In this example, we told the Intent object what component we wanted to activate (SecondActivity). This kind of Intent object is called an explicit Intent, simply because we’re very precise on what we want to activate. Another type of Intent is called an implicit Intent, which is what we’ll discuss in the next section.

Implicit Intents

There are two kinds of Intent, an implicit and an explicit one. You can think of the two types of Intent this way; let’s imagine asking someone to buy some sugar. If we instruct “could you please buy some sugar” with no further details, this would be equivalent to an implicit Intent because that person could buy the sugar anywhere. On the other hand, if we gave instructions like “could you please go to the ABC store on third street and buy some sugar,” this would be equivalent to an explicit Intent. Our earlier example in Listing 8-2 is an explicit Intent because we told the Intent specifically which component to activate.

Implicit Intents, on the other hand, are very powerful because they allow an application to take advantage of other applications. Your app can gain functionalities that you did not write yourself. For example, you can create an Intent that opens the camera, shoots, and saves a photo, without writing any camera-specific code.

The purpose of implicit Intent is for you to use a functionality that doesn’t exist within your app, because if the feature exists within your app, you would have used explicit Intents in the first place. Using an implicit Intent is a way to ask the Android Runtime to find an application somewhere on the device that can service your request.

In an explicit Intent, we tell the Intent which specific component to activate. In an implicit Intent, we tell the Intent what we’d like to do instead; for example, if we wanted to launch a browser and navigate to https://apress.com, here’s how to do it:
  1. 1.

    Create an Intent object.

     
  2. 2.

    Tell it what to do by specifying some actions, for example, “view a map,” “call a number,” “take a picture,” “view a web page,” and so on.

     
  3. 3.

    Give it some information or data; for example, if we want to launch a browser and navigate to a specific web page, we need to tell the Intent the URI of the web page.

     
  4. 4.

    Finally, we launch the Intent.

     
Listing 8-3 shows how to do this in code.
Intent intent = new Intent(); ❶
intent.setAction(Intent.ACTION_VIEW); ❷
intent.setData(Uri.parse("https://apress.com")); ❸
startActivity(intent); ❹
Listing 8-3

Example Intent to browse a web page

Create the Intent object using the no-arg constructor.

Set the Intent action. In this example, we’d like to view something; it could be a contact, a web page, a map, a picture somewhere, and so on. At this point, the Android Runtime doesn’t know yet what you want to view. ACTION_VIEW is one of the many Intent Actions you can use. You can find other kinds of Action in the official Android’s website: https://developer.android.com/guide/components/intents-common.

Set its data. At this point, the Android Runtime has a pretty good idea of what you want to do. In this example, the Uri is a web page. Android is pretty smart to figure out that we’d like to view a web page.

Android will search every app on the device, which will best match this request. If it finds more than one app, it will let the user choose which one. If it finds only one, it will simply launch that app.

Alternatively, you can set the Intent’s action and data by passing them to the Intent’s constructor, like this:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://apress.com"));

Any component that can respond to this Intent does not need to be running to receive the Intent. Remember that all applications need to have a manifest file. Each application declares its capabilities in the manifest file, specifically through the <intent-filter> section. Android’s package manager has all the info of all the applications installed on the device. Android’s runtime only needs the information on the manifest file to see which among the apps are capable or eligible to respond to the Intent. The Android Runtime inspects the Intent object’s content and then compares it to the Intent filters of all components. An Intent filter is a way for Android components to declare their capabilities to the Android system.

To see this in action, let’s create another project with an empty Activity. Assuming you’ve already done that, let’s work on the MainActivity class. We will create three action triggers; we could use Buttons, but let’s use the Options menu for this exercise. Listing 8-4 shows the annotated code for MainActivity.
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
  private final String TAG = getClass().getName();
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) { ❶
    menu.add("View Apress"); ❷
    menu.add("View Map");
    menu.add("Call number");
    return super.onCreateOptionsMenu(menu);
  }
  @Override
  public boolean onOptionsItemSelected(@NonNull MenuItem item) { ❸
    Intent intent = null;
    Uri uri;
    switch(item.toString()) {  ❹
      case "View Apress":
        Log.d(TAG, "View Action");
        uri = Uri.parse("https://apress.com");
        intent = new Intent(Intent.ACTION_VIEW, uri); ➀
        break;
      case "View Map":
        uri = Uri.parse(("geo:40.7113399,-74.0263469"));
        intent = new Intent(Intent.ACTION_VIEW, uri); ➁
        break;
      case "Call number":
        Log.d(TAG, "Call number");
        uri = Uri.parse(("tel:639285083333"));
        intent = new Intent(Intent.ACTION_CALL, uri); ➂
    }
    startActivity(intent);
    return true;
  }
}
Listing 8-4

MainActivity

Let’s override the onCreateOptionsMenu() callback; this will be called shortly after the onCreate() callback. Overriding this method allows us to build a dynamic menu programmatically.

Add a menu item dynamically.

Whenever the user clicks one of the Menu Items, the onOptionsItemSelected is called; this is where we will handle the menu clicks.

The item parameter can tell us which Menu Item was clicked. We’re converting it to String to use it to route our program logic using a switch statement.

Create an Intent and set its action and data to view the Apress website.

Create an Intent and set its action and data to view a location.

Create an Intent and set its action and data to call a specific number.

Figure 8-4 shows the app at runtime.
../images/457413_2_En_8_Chapter/457413_2_En_8_Fig4_HTML.jpg
Figure 8-4

Implicit Intent project, running

Summary

  • Intents are used for component activation.

  • There are two kinds of Intents, implicit and explicit ones.

  • Explicit Intents let us work with multiple activities. You can activate a specific Activity using an explicit Intent.

  • Implicit Intents extend the functionality of your application. They allow your application to do things that are outside the functionality of your app.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.189.247