Intent
Intents are asynchronous messages which allow application components to request functionality from other Android components. Intents allow you to interact with components from the same applications as well as with components contributed by other applications. For example, an activity can start an external activity for taking a picture.
Intents are objects of the android.content.Intent
type. Your code can send them to the Android system defining the components you are targeting. For example, via thestartActivity()
method you can define that the intent should be used to start an activity.
An intent can contain data via a Bundle
. This data can be used by the receiving component.
Starting activities
To start an activity, use the method startActivity(intent)
. This method is defined on the Context
object which Activity
extends.
The following code demonstrates how you can start another activity via an intent.
# Start the activity connect to the
# specified class
Intent i = new Intent(this, ActivityTwo.class);
startActivity(i);
Sub-activities
Activities which are started by other Android activities are called sub-activities. This wording makes it easier to describe which activity is meant.
Starting services
You can also start services via intents. Use the startService(Intent)
method call for that.
Intents types
Different types of intents
Android supports explicit and implicit intents.
An application can define the target component directly in the intent (explicit intent) or ask the Android system to evaluate registered components based on the intent data (implicit intents).
Explicit Intents
Explicit intents explicitly define the component which should be called by the Android system, by using the Java class as identifier.
The following shows how to create an explicit intent and send it to the Android system. If the class specified in the intent represents an activity, the Android system starts it.
Intent i = new Intent(this, ActivityTwo.class);
i.putExtra("Value1", "This value one for ActivityTwo ");
i.putExtra("Value2", "This value two ActivityTwo");
Explicit intents are typically used within on application as the classes in an application are controlled by the application developer.
Implicit Intents
Implicit intents specify the action which should be performed and optionally data which provides content for the action.
For example, the following tells the Android system to view a webpage. All installed web browsers should be registered to the corresponding intent data via an intent filter.
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.vogella.com"));
startActivity(i);
If an implicit intent is sent to the Android system, it searches for all components which are registered for the specific action and the fitting data type.
If only one component is found, Android starts this component directly. If several components are identified by the Android system, the user will get a selection dialog and can decide which component should be used for the intent.
Data transfer between activities
Data transfer to the target component
An intent contains certain header data, e.g., the desired action, the type, etc. Optionally an intent can also contain additional data based on an instance of the Bundle
class which can be retrieved from the intent via the getExtras()
method.
You can also add data directly to the Bundle
via the overloaded putExtra()
methods of the Intent
objects. Extras are key/value pairs. The key is always of type String
. As value you can use the primitive data types (int
, float
, ...) plus objects of type String
, Bundle
, Parceable
and Serializable
.
The receiving component can access this information via the getAction()
and getData()
methods on the Intent
object. This Intent
object can be retrieved via the getIntent()
method.
The component which receives the intent can use the getIntent().getExtras()
method call to get the extra data. That is demonstrated in the following code snippet.
Bundle extras = getIntent().getExtras();
if (extras == null) {
return;
}
// get data via the key
String value1 = extras.getString(Intent.EXTRA_TEXT);
if (value1 != null) {
// do something with the data
}
Example: Using the share intent
Lots of Android applications allow you to share some data with other people, e.g., the Facebook, G+, Gmail and Twitter application. You can send data to one of these components. The following code snippet demonstrates the usage of such an intent within your application.
// this runs, for example, after a button click
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "News for you!");
startActivity(intent);
Retrieving result data from a sub-activity
An activity can be closed via the back button on the phone. In this case the finish()
method is performed. If the activity was started with the startActivity(Intent)
method call, the caller requires no result or feedback from the activity which now is closed.
If you start the activity with the startActivityForResult()
method call, you expect feedback from the sub-activity. Once the sub-activity ends, the onActivityResult()
method on the sub-activity is called and you can perform actions based on the result.
In the startActivityForResult()
method call you can specify a result code to determine which activity you started. This result code is returned to you. The started activity can also set a result code which the caller can use to determine if the activity was canceled or not.
The sub-activity uses the finish()
method to create a new intent and to put data into it. It also sets a result via the setResult()
method call.
The following example code demonstrates how to trigger an intent with the startActivityForResult()
method.
public void onClick(View view) {
Intent i = new Intent(this, ActivityTwo.class);
i.putExtra("Value1", "This value one for ActivityTwo ");
i.putExtra("Value2", "This value two ActivityTwo");
// set the request code to any code you like,
// you can identify the callback via this code
startActivityForResult(i, REQUEST_CODE);
}
If you use the startActivityForResult()
method, then the started activity is called a sub-activity.
If the sub-activity is finished, it can send data back to its caller via an Intent. This is done in the finish()
method.
@Override
public void finish() {
// Prepare data intent
Intent data = new Intent();
data.putExtra("returnKey1", "Swinging on a star. ");
data.putExtra("returnKey2", "You could be better then you are. ");
// Activity finished ok, return the data
setResult(RESULT_OK, data);
super.finish();
}
Once the sub-activity finishes, the onActivityResult()
method in the calling activity is called.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data.hasExtra("returnKey1")) {
Toast.makeText(this, data.getExtras().getString("returnKey1"),
Toast.LENGTH_SHORT).show();
}
}
}
Defining intent filters
Intent filter
Intents are used to signal to the Android system that a certain event has occurred. Intents often describe the action which should be performed and provide data upon which such an action should be done. For example, your application can start a browser component for a certain URL via an intent. This is demonstrated by the following example.
String url = "http://www.vogella.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
But how does the Android system identify the components which can react to a certain intent?
A component can register itself via an intent filter for a specific action and specific data. An intent filter specifies the types of intents to which an activity, service, or broadcast receiver can respond to by declaring the capabilities of a component.
Android components register intent filters either statically in the AndroidManifest.xml or in case of a broadcast receiver also dynamically via code. An intent filter is defined by its category, action and data filters. It can also contain additional meta-data.
If an intent is sent to the Android system, the Android platform runs a receiver determination. It uses the data included in the intent. If several components have registered for the same intent filter, the user can decide which component should be started.
Defining intent filter
You can register your Android components via intent filters for certain events. If a component does not define one, it can only be called by explicit intents. This chapter gives an example for registering a component for an intent. The key for this registration is that your component registers for the correct action, mime-type and specifies the correct meta-data.
If you send such an intent to your system, the Android system determines all registered Android components for this intent. If several components have registered for this intent, the user can select which one should be used.
Example: Register an activity as browser
The following code will register an Activity for the Intent which is triggered when someone wants to open a webpage.
<activity android:name=".BrowserActivitiy"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http"/>
</intent-filter>
</activity>
Example: Register an activity for the share intent
The following example registers an activity for the ACTION_SEND
intent. It declares itself only relevant for the text/plain mime type.
<activity
android:name=".ActivityTest"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
If a component does not define an intent filter, it can only be called by explicit intents.