Android Intents Filters
An Android Intent is an abstract description of an operation to be performed. It can be used with `startActivity` to launch an activity, `broadcastIntent` to send an intent to any interested Broadcast Receiver components, and `startService(Intent)` or `bindService(Intent, ServiceConnection, int)` to communicate with background services.
The Intent itself (an Intent object) is a passive data structure holding an abstract description of the operation to be performed.
For example, you have an activity that needs to open an email client and send an email via an Android device. For this purpose, your activity needs to send an `ACTION_SEND` intent with an appropriate selector to the Android intent handler. The specified selector provides the appropriate UI for the user to decide how to send their email data.
```java
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
email.putExtra(Intent.EXTRA_EMAIL, recipients);
email.putExtra(Intent.EXTRA_SUBJECT, subject.getText().toString());
email.putExtra(Intent.EXTRA_TEXT, body.getText().toString());
startActivity(Intent.createChooser(email, "Choose an email client from..."));
The above syntax calls the `startActivity` method to launch the email activity. The code execution result looks like this:

For example, you have an activity that needs to open a URL in a browser on an Android device. For this purpose, your activity sends an `ACTION_WEB_SEARCH` intent to the Android intent handler to open the given URL in a browser. The intent handler resolves a series of activities and selects the one that best fits your intent, in this case, the Web browser activity. The intent handler passes your web address to the Web browser and launches the Web browser activity.
```java
String q = "";
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, q);
startActivity(intent);
The above example will search for "www..com" on the Android search engine and present the results for the keyword in an activity.
Each componentβactivity, service, and broadcast receiverβhas a separate mechanism for delivering intents.
| No. | Method and Description |
| --- | --- |
| 1 | `Context.startActivity()`: The intent is passed to this method to start a new activity or make an existing activity do something new. |
| 2 | `Context.startService()`: The intent is passed to this method to initialize a service or send new information to an ongoing service. |
| 3 | `Context.sendBroadcast()`: The intent is passed to this method, and the information will be delivered to all interested broadcast receivers. |
* * *
## Intent Object
The Intent object is a bundle of information that is passed to a component that receives an intent, just like information is passed to the Android system.
The Intent object includes the following components, depending on what is to be communicated or executed.
### Action
This is a mandatory part of the Intent object, represented as a string. In a broadcast intent, the action is reported once it occurs. The action largely determines how the rest of the intent is organized. The `Intent` class defines a series of action constants corresponding to different intents. Here is a list of (#).
The action in an Intent object can be set using the `setAction()` method and read using the `getAction()` method.
### Data
Adds a data specification to the intent filter. This specification can be just a data type (like a MIME type attribute), a URI, or both a data type and a URI. The URI is specified by its different parts.
These attributes that specify the URL format are optional but mutually independent:
* If the intent filter does not specify a scheme, all other URI attributes are ignored.
* If no host is specified for the filter, the port attribute and all path attributes are ignored.
The `setData()` method specifies data as a URI only, `setType()` specifies data as a MIME type only, and `setDataAndType()` specifies both a URI and a MIME type. The URI is read via `getData()`, and the type via `getType()`.
Here are some examples of action/data pairs:
| No. | Action/Data Pair and Description |
| --- | --- |
| 1 | `ACTION_VIEW content://contacts/people/1`: Display information about user ID 1. |
| 2 | `ACTION_DIAL content://contacts/people/1`: Display the phone dialer and populate it with data for user 1. |
| 3 | `ACTION_VIEW tel:123`: Display the phone dialer and populate it with the given number. |
| 4 | `ACTION_DIAL tel:123`: Display the phone dialer and populate it with the given number. |
| 5 | `ACTION_EDIT content://contacts/people/1`: Edit information about user ID 1. |
| 6 | `ACTION_VIEW content://contacts/people/`: Display a list of users for viewing. |
| 7 | `ACTION_SET_WALLPAPER`: Display the wallpaper picker. |
| 8 | `ACTION_SYNC`: Synchronize data. The default value is: `android.intent.action.SYNC` |
| 9 | `ACTION_SYSTEM_TUTORIAL`: Launch a platform-defined tutorial (default tutorial or startup tutorial). |
| 10 | `ACTION_TIMEZONE_CHANGED`: Notify when the time zone has changed. |
| 11 | `ACTION_UNINSTALL_PACKAGE`: Run the default uninstaller. |
### Category
Category is an optional part of the intent, a string containing additional information about the type of component that needs to handle the intent. The `addCategory()` method adds a category to the intent object, the `removeCategory()` method removes a previously added category, and `getCategories()` gets all categories set on the intent object. Here is a list of (#).
You can refer to the intent filters in the following sections to understand how we use categories to select the appropriate activity for a corresponding intent.
### Extra Data
This is additional information in the form of key-value pairs passed to the component that needs to handle the intent. It is set via the `putExtras()` method and read via the `getExtras()` method. Here is a list of (#).
### Flags
These flags are optional parts of the intent that indicate how the Android system should launch an activity, how it should be handled after launching, etc.
| No. | Flag and Description |
| --- | --- |
| 1 | `FLAG_ACTIVITY_CLEAR_TASK`: If set in the intent and passed via `Context.startActivity`, this flag will cause all existing tasks associated with that activity to be cleared before the activity is started. The activity will become the root of an empty task, and all old activities will be finished. This flag can be used in conjunction with `FLAG_ACTIVITY_NEW_TASK`. |
| 2 | `FLAG_ACTIVITY_CLEAR_TOP`: If this flag is set, the activity will be launched within the currently running task. This does not start a new instance of the activity; all activities above it are closed, and this intent is delivered as a new intent to the existing (currently top) activity. |
| 3 | `FLAG_ACTIVITY_NEW_TASK`: This flag is generally used to make an activity behave like a "launcher" style action: provide the user with data that can be run independently and launch a complete, independent activity. |
### Component Name
The component name object is an optional field that represents the activity, service, or broadcast receiver class. If set, the intent object is delivered to an instance of the designated class. Otherwise, Android uses other information in the intent to locate a suitable target. The component name is set via `setComponent()`, `setClass()`, or `setClassName()`, and retrieved via `getComponent()`.
* * *
## Types of Intents
Android supports two types of intents.

### Explicit Intents
Explicit intents are used to connect the internal world of an application. Assuming you need to connect one activity to another, we can use an explicit intent. The following diagram shows connecting the first activity to the second activity by clicking a button.

These intents specify the target component by name and are generally used for internal information within an applicationβsuch as an activity launching a subordinate activity or launching a sibling activity. For example:
```java
// Explicit intent by specifying the class name
Intent i = new Intent(FirstActivity.this, SecondActivity.class);
// Start the target activity
startActivity(i);
### Implicit Intents
These intents do not name a target; the component name field is empty. Implicit intents are often used to activate components in other applications. For example:
```java
Intent read1 = new Intent();
read1.setAction(android.content.Intent.ACTION_VIEW);
read1.setData(ContactsContract.Contacts.CONTENT_URI);
startActivity(read1);
The above code will produce the following result:

The target component receiving the intent can use the `getExtras()` method to retrieve the extra data sent by the source component. For example:
```java
// Get the Bundle object at the appropriate place in the code
Bundle extras = getIntent().getExtras();
// Extract data by key
String value1 = extras.getString("Key1");
String value2 = extras.getString("Key2");
* * *
## Example
The following example demonstrates using Android Intents to launch various built-in Android application functions.
| Step | Description |
| --- | --- |
| 1 | Create an Android application using the Android Studio IDE, naming it Intent filter, with the package name `com..intentfilter`. When creating the project, ensure the target SDK and compile with the latest version of the Android SDK to use advanced APIs. |
| 2 | Modify the `src/com..intentfilter/MainActivity.java` file and add code to define two listeners for the two buttons "Launch Browser" and "Launch Phone". |
| 3 | Modify the `res/layout/activity_main.xml` layout file, adding 3 buttons in a linear layout. |
| 4 | Launch the Android emulator to run the application and verify the results of the changes made. |
Below is the content of the `src/com..intentfilter/MainActivity.java` file:
```java
package com..intentfilter;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
public class MainActivity extends ActionBarActivity {
Button b1, b2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1 = (Button) findViewById(R.id.button);
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse(""));
startActivity(i);
}
});
b2 = (Button) findViewById(R.id.button2);
b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse("tel:9510300000"));
startActivity(i);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Below is the content of the `res/layout/activity_main.xml` file:
```xml
Below is the content of `res/values/strings.xml`, defining two new constants.
```xml
Intent filter
Settings
Below is the default content of `AndroidManifest.xml`:
```xml
Let's run the modified Intent filter application. I assume you have created an AVD during the environment setup. Open the activity file in your project and click the  icon in the toolbar to run the application in Android Studio. Android Studio installs the application on the AVD and launches it. If everything goes well, the following will be displayed on the emulator window:

Now click the "Launch Browser" button. This will launch a browser based on the configuration and display as follows:

In a similar way, you can click the "Launch Phone" button to open the phone interface, which will allow you to dial the given phone number.
* * *
## Intent Filters
You have already seen how to use intents to invoke other activities. The Android operating system uses filters to specify a set of activities, services, and broadcast receivers that handle intents, based on the action, category, and data patterns specified in the intent. In the manifest file, the `` element is used to list the corresponding actions, categories, and data types in activities, services, and broadcast receivers.
The following example shows a part of an `AndroidManifest.xml` file, specifying that an activity `com..intentfilter.CustomActivity` can be invoked via the set action, category, and data:
```xml
When an activity is defined by the above filter, other activities can invoke this activity in the following ways: using `android.intent.action.VIEW`, using the `com..intentfilter.LAUNCH` action, and providing the `android.intent.category.DEFAULT` category.
The `` element specifies the data type expected by the activity to be invoked. In the above example, the custom activity expects data starting with "http://".
There are situations where, through filters, an intent will be delivered to multiple activities or services, and the user will be asked which component to launch. If no target component is found, an exception will occur.
Before invoking an activity, there is a series of Android check tests:
* The filter `` must list one or more actions; it cannot be empty. The filter must contain at least one `` element, otherwise it will block all intents. If multiple actions are mentioned, Android tries to match one of the mentioned actions before invoking the activity.
* The filter `` may list 0, 1, or more categories. If no categories are mentioned, Android passes this test. If multiple categories are mentioned, the intent passes the type test only if each category in the intent object matches one of the categories in the filter.
* Each `` element can specify a URI and a data type (MIME media type). There are independent attributes for each part of the URI: scheme, host, port, and path. An intent containing a URI and a type passes the data type part of the test only if its type matches one of the types listed in the filter.
* * *
## Example
The following example is a modification of the previous example. Here we will see how Android resolves conflicts if an intent invokes two defined activities; how to use filters to invoke a custom activity; and what exception occurs if no suitable activity is defined for an intent.
| Step | Description |
| --- | --- |
| 1 | Create an Android application using the Android Studio IDE, naming it Intent filter, with the package name `com..intentfilter`. When creating the project, ensure the target SDK and compile with the latest version of the Android SDK to use advanced APIs. |
| 2 | Modify the `src/com..intentfilter/MainActivity.java` file and add code to define two listeners for the two buttons "Launch Browser" and "Launch Phone". |
| 3 | Modify the `res/layout/activity_main.xml` layout file, adding 3 buttons in a linear layout. |
| 4 | Launch the Android emulator to run the application and verify the results of the changes made. |
YouTip