Wednesday, August 29, 2012

Intent & Intent Filters

What is Intent?

Intent is kind of asynchronous message to Android components. Android component reacts on that message. Intent can be sent by an Activity to Android system which can start another Activity.

This is totally asynchronous, so it is stateless. Starting another activity using Intent is loosely coupled.

Intent is a class in android.content package. To send an intent, you have to create an instance of Intent class.

Android system receive message from Intent and based on that message system decide what to do next.

Other then message Intent can contain some date to send. If you have scene precious article of Login, I have sent user name to next activity using Intent.

Intent can call user define activity or system activities like Browser, Contact List, Call Activity, etc. To send intent to system activities there are constants created in android. User can use those predefined constants to intent those activities.

Intent can be used with startActivity() to launch an Activity, it can be broadcastIntent() to send it to interested BroadcastReceiver component, and startService(Intent)  or bindService(Intent, ServiceConnection, int) to communicate with a background service.

Intent Object
An intent object is bundle of information. It contain information of component that receives the intent such as the action to be taken and the data to act on plus information of the android system such as the category of component that should handle the intent and instructions on how to launch a target activity.

Main information in intent are:
  • Action: The general action to be performed, such as ACTION_VIEW, ACTION_EDIT, ACTION_MAIN, etc.
  • Data: The data to operate on, such as a person record in the contacts database, expressed as a Uri.
Other then above two main information in Intent, there are many optional attributes you can include with an Intent.
  • category -- Gives additional information about the action to execute. For example, CATEGORY_LAUNCHER means it should appear in the Launcher as a top-level application, while CATEGORY_ALTERNATIVE means it should be included in a list of alternative actions the user can perform on a piece of data.

  • type -- Specifies an explicit type (a MIME type) of the intent data. Normally the type is inferred from the data itself. By setting this attribute, you disable that evaluation and force an explicit type.

  • component -- Specifies an explicit name of a component class to use for the intent. Normally this is determined by looking at the other information in the intent (the action, data/type, and categories) and matching that with a component that can handle it. If this attribute is set then none of the evaluation is performed, and this component is used exactly as is. By specifying this attribute, all of the other Intent attributes become optional.

  • extras -- This is a Bundle of any additional information. This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body, etc.

Intent Resolution

There are two main forms of intents you can use.
  • Explicit Intents have specified a component (via setComponent(ComponentName) or setClass(Context, Class)),  which provides the exact class to be run. Often these will not include any other information, simply being a way for an application to launch various internal activities it has as the user interacts with the application.
  • Implicit Intents have not specified a component; instead, they must include enough information for the system to determine which of the available components is best to run for that intent.

Android delivers an explicit intent to an instance of the designated target class. Nothing in the Intent object other than the component name matters for determining which component should get the intent. 

A different strategy is needed for implicit intents. In the absence of a designated target, the Android system must find the best component (or components) to handle the intent — a single activity or service to perform the requested action or the set of broadcast receivers to respond to the broadcast announcement. It does so by comparing the contents of the Intent object to intent filters, structures associated with components that can potentially receive intents. Filters advertise the capabilities of a component and delimit the intents it can handle. They open the component to the possibility of receiving implicit intents of the advertised type. If a component does not have any intent filters, it can receive only explicit intents. A component with filters can receive both explicit and implicit intents.

Only three aspects of an Intent object are consulted when the object is tested against an intent filter: 
  • Action
  • Date (both URI and data type)
  • Category

Intent Filter

If an Intent is send to the Android system, it will determine suitable applications for this Intent. If several components have been registered for this type of Intent, Android offers the user the choice to open one of them. 

This determination is based on IntentFilters. An IntentFilter specifies the types of Intent that an activity, service, or broadcast receiver can respond to. An IntentFilter declares the capabilities of a component. It specifies what an Activity or Service can do and what types of broadcasts a Receiver can handle. It allows the corresponding component to receive Intents of the declared type. 

IntentFilter are typically defined via the AndroidManifest.xml file. For BroadcasrReceiver it is also possible to define them in coding. An IntentFilter is defined by its category, action and data filters. It can also contain additional metadata.

To inform the system which implicit intents they can handle, activities, services, and broadcast receivers can have one or more intent filters. Each filter describes a capability of the component, a set of intents that the component is willing to receive. It, in effect, filters in intents of a desired type, while filtering out unwanted intents — but only unwanted implicit intents (those that don't name a target class). An explicit intent is always delivered to its target, no matter what it contains; the filter is not consulted. But an implicit intent is delivered to a component only if it can pass through one of the component's filters.  

An intent filter is an instance of the IntentFilter class. However, since the Android system must know about the capabilities of a component before it can launch that component, intent filters are generally not set up in Java code, but in the application's manifest file (AndroidManifest.xml) as <intent-filter> elements. (The one exception would be filters for broadcast receivers that are registered dynamically by calling Context.registerReceiver(); they are directly created as IntentFilter objects.)

A filter has fields that parallel the action, data, and category fields of an Intent object. An implicit intent is tested against the filter in all three areas. To be delivered to the component that owns the filter, it must pass all three tests. If it fails even one of them, the Android system won't deliver it to the component — at least not on the basis of that filter. However, since a component can have multiple intent filters, an intent that does not pass through one of a component's filters might make it through on another.

1 comment:

  1. It is really a great work and the way in which you are sharing the knowledge is excellent.Thanks for helping me to understand basic concepts. As a beginner in android programming your post help me a lot.Thanks for your informative article. Android Training in velachery | Android Training institute in chennai