By liran bh | 1/11/2017 | General |Beginners

Android Intents and Intent Filters

Android Intents and Intent Filters

This guide will introduce you to one of the most important components in Android, Intents.

 

We will study:

  • What are Intents?
  • How they support communication between components?
  • Design mechanism.
  • Intent Filters.
  • Actions and categories.
  • Explicit and Implicit Intents.
  • Sticky Intents.
  • Pending Intents.

 

Looks like we have a long way to go, so let’s dive into the sections.

Intents

An Intent is an "intention" to perform an action.

 

An intent is an abstract description of an operation to be performed. It can be used with startActivity to launch an Activity, broadcastIntent to send it to any interested BroadcastReceiver components, and startService(Intent) or bindService(Intent, ServiceConnection, int) to communicate with a background Service.

>>> Intent defines Communication mechanism between various Android components.

 

An Intent is basically a message to say you did or want something to happen. Depending on the intent, apps or the OS might be listening for it and will react accordingly. Think of it as a blast email to a bunch of friends, in which you tell your friend John to do something, or to friends who can do X ("intent filters"), to do X. The other folks will ignore the email, but John (or friends who can do X) will react to it.

 

To listen for an broadcast intent (like the phone ringing, or an SMS is received), you implement a broadcast receiver, which will be passed the intent. To declare that you can handle another's app intent like "take picture", you declare an intent filter in your app's manifest file.

 

If you want to fire off an intent to do something, like pop up the dialer, you fire off an intent saying you will.

Forms of Intents

There are two primary forms of intents we will use. They are:

 

  • 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.

 

Implicit Intent

When you create an implicit intent, the Android system finds the appropriate component to start by comparing the contents of the intent to the intent filters declared in the manifest file of other apps on the device. If the intent matches an intent filter, the system starts that component and delivers it the Intent object.

 

Let’s look at an example of implicit intent.

// Create the text message with a string

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
   startActivity(sendIntent);
}

 

 

In the above example, we define what we want to do and Android will itself check about which application can carry out our requested action and start that application. If more than one app can carry out the action, we will see an app chooser.

 

Caution: It's possible that a user won't have any apps that handle the implicit intent you send to startActivity(). Or, an app may be inaccessible because of profile restrictions or settings put into place by an administrator. If that happens, the call fails and your app crashes. To verify that an activity will receive the intent, call resolveActivity() on your Intent object. If the result is non-null, there is at least one app that can handle the intent and it's safe to call startActivity(). If the result is null, do not use the intent and, if possible, you should disable the feature that issues the intent. The following example shows how to verify that the intent resolves to an activity. This example doesn't use a URI, but the intent's data type is declared to specify the content carried by the extras.

Explicit intents

If we build a service in our app, named DownloadService, designed to download a file over the network, you can start it with the following sample:

 

 

// Executed in an Activity, so 'this' is the Context

// The fileUrl is a string URL, such as "http://www.example.com/image.png"

Intent downloadIntent = new Intent(this, DownloadService.class);

downloadIntent.setData(Uri.parse(fileUrl));

startService(downloadIntent);

The Intent(Context, Class) constructor supplies the app Context and the component a Class object. As such, this intent explicitly starts the DownloadService class in the app.

Intent Objects

An Intent object is a bundle of information which is used by the Android component that receives the intent as well as information used by the Android OS. An Intent object can have the below components based on what it is communicating or going to perform:

Action

This is mandatory part of the Intent object and is a string naming the action to be performed or, in the case of broadcast intents, the action that took place and is being reported. The action largely determines how the rest of the intent object is structured. The Intent class defines a number of action constants corresponding to different intents. Here is a list of Android Intent Standard Actions.

The action in an Intent object can be set by the setAction() method and read by getAction().

Data

Adds a data specification to an intent filter. The specification can be just a data type (the mimeType attribute), just a URI, or both a data type and a URI. A URI is specified by separate attributes for each of its parts. These attributes that specify the URL format are optional, but also mutually dependent:

  • If a scheme is not specified for the intent filter, all the other URI attributes are ignored.
  • If a host is not specified for the filter, the port attribute and all the path attributes are ignored.

 

The setData() method specifies data only as a URI, setType() specifies it only as a MIME type, and setDataAndType() specifies it as both a URI and a MIME type. The URI is read by getData() and the type by getType().

Category

The category is an optional part of Intent object and it's a string containing additional information about the kind of component that should handle the intent. The addCategory() method places a category in an Intent object, removeCategory() deletes a category previously added, and getCategories() gets the set of all categories currently in the object.

Extras

This will be in key-value pairs for additional information that should be delivered to the component handling the intent. The extras can be set and read using the putExtras() and getExtras() methods respectively.

 

Intent Filters

You have seen how an Intent has been used to call another activity. Android OS uses filters to pinpoint the set of components (Activities, Services, and Broadcast receivers) that can handle the Intent with help of specified set of action, categories, data scheme associated with an Intent. We will use <intent-filter> element in the manifest file to list down actions, categories and data types associated with any activity, service, or broadcast receiver.

 

Following is an example of a part of AndroidManifest.xml file to specify an activity com.discoversdk.My Application.CustomActivity which can be invoked by either of the two mentioned actions, one category, and one data:

 

<activity android:name=".CustomActivity"
  android:label="@string/app_name">
  
  <intent-filter>
     <action android:name="android.intent.action.VIEW" />
     <action android:name="com.discoversdk.My Application.LAUNCH" />
     <category android:name="android.intent.category.DEFAULT" />
     <data android:scheme="http" />
  </intent-filter>
</activity>

 

Once this activity is defined along with the above mentioned filters, other activities will be able to invoke this activity using either the android.intent.action.VIEW, or using the com.example.My Application.LAUNCH action provided their category is android.intent.category.DEFAULT.

 

The <data> element specifies the data type expected by the activity to be called and for above example our custom activity expects the data to start with the "http://".

 

There may be a situation that an intent can pass through the filters of more than one activity or service, the user may be asked which component to activate through a file chooser. An exception is raised if no target or component is found to handle the intent.

 

There are following test Android checks before invoking an activity −

  • A filter <intent-filter> may list more than one action as shown above but this list cannot be empty; a filter must contain at least one <action> element, otherwise it will block all intents. If more than one action is mentioned then Android tries to match one of the mentioned actions before invoking the activity.
  • A filter <intent-filter> may list zero, one or more than one categories. If there is no category mentioned then Android always passes this test but if more than one category is mentioned then for an intent to pass the category test, every category in the Intent object must match a category in the filter.
  • Each <data> element can specify a URI and a data type (MIME media type). There are separate attributes like scheme, host, port, and path for each part of the URI. An Intent object that contains both a URI and a datatype passes the data type part of the test only if its type matches a type listed in the filter.

 

Let’s look at AndroidManifest.xml to create an implicit intent using an intent-filter,

<activity
 android:name=".HelloWorld"
 android:label="@string/app_name">
   <intent-filter>
     <action
       android:name="android.intent.action.VIEW"/>
     <category
       android:name="android.intent.category.DEFAULT"/>
     <category
       android:name="android.intent.category.BROWSABLE"/>
     <data
       android:scheme="http"
       android:host="discoversdk.com"/>
   </intent-filter>

</activity>

 

In the activity, we can launch Activity HelloWorld.java as,

Intent intent = new Intent (Intent.ACTION_VIEW, Uri.parse("http://discoversdk.com"));

startActivity(intent);

 

Conclusion

This article introduced you to the communication mechanism implemented in Android using Intents and Intent filters. Use these components to build better apps!

By liran bh | 1/11/2017 | General

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now