Free Android app covering all aspects of addiction, including prevention and treatment

Intents and Intent Filters

  • Written by  Clive

Getting to know Intents and Intent Filters

Android Intents and Intent Filters icon

Intents are messages that you can pass around between your app components. You can also send them to components in other apps. This enables you to create powerful applications where you can use other app’s components to perform tasks for you, such as playing music, sending email, and taking pictures.

Here are some of the things that you can do with intents:

  • Start activities
  • Start Services
  • Deliver broadcasts

The Android System also uses intents to signal changes such as low battery, incoming sms messages and phone calls. You can listen for these intent messages in your apps.  You can also use intents to pass data.

There are two types of intents

  • Explicit Intents – you must name the component that will receive the intent. You’ll usually use Explicit Intents in your own app’s where you know the component’s class
  • Implicit Intents – the component isn’t named so you won’t know which component will receive the intent. You declare a general action that the component must perform. The System then looks for suitable components by matching the contents of the intent to intent filters of all the apps on the device. If there is a match, then the system starts that component and delivers the intent object to it. If there are a number of matches, a chooser dialog is displayed, allowing the user to select the suitable component

The Gate keepers: Intent filters

You use filters to deny or allow intents to reach your app components.

Lay down the rules: Declare you intent filters

You must declare intent filters for each component that you want to receive an intent. The System will then know which intents your app can receive.

You can declare the filters in the manifest and in some cases also programmatically:

  • Activity filters – must be declared in the manifest
  • Broadcast Receivers – you can register these filters dynamically or in the manifest. You may want to look at Android Broadcast Receivers: a tutorial for more on broadcast receivers

Each filter specifies the type of intent it accepts, based on the intent’s action, data and category. The system then compares the intent to your filters and only delivers it to your app component if there is a match.

You should declare separate filters for each unique job that a component can do. For example, an image app can have two filters, one to view an image and another to edit an image.

Putting it together: The parts of an intent

Intents contain information which the system uses to find the correct component to handle the intent.

You can include the following information in an intent:

  • Component name
  • Action
  • Data
  • Category
  • Extras
  • flags

Component name

If it’s an explicit intent, then you need to include the name of the component that you want to start. Implicit intents don’t need a component name

Action

This is the action that we want the component to perform. It determines the rest of the intents structure, such as the contents of the data and extras elements.

You’d usually use actions defined by the Intent class’s action constants. Here are a few examples:

    • ACTION_VIEW – use it with startActivity() if the activity has information to show, for example a photo
    • ACTION_SEND – use it with startActivity() if you have data to share, for example  email
    • See the Intent class for more action constants

You can also specify your own actions.

Data

Data is a URI object referencing the data to be acted on. The action will be performed on this data. It could be, or include, the MIME type for the data. For example, an email address or telephone number.

Category

The category contains additional information about the component that should handle the intent. You can have a number of category descriptions but it’s not required. Here are two examples:

    • CATEGORY_BROWSABLE – the target activity allows itself to be started by a web browser to display data referenced by a link, for example an image
    • CATEGORY_LAUNCHER – the target activity is the initial activity of a task. And is listed in the system’s app launcher. An example is the activity that launches your app

Extras

You can include additional information in the form of key-value-pairs in the intent. Simply add the data to the intent using one of the putExtra methods.

Have a look at Passing data between activities where we show you how to exchange primitive data between activities.

Flags

Flags contain extra information for the system on how it should handle the intent.

Getting the message: Receiving an implicit intent

App components can only receive an intent if it makes it through the intent filters.

Check the credentials: Filtering the Intents

Each filter is defined by the element in the app’s manifest (or programmatically). This is where you specify the type of intent to accept using the following elements (in the manifest):

  • - specifies which intent action the component will accept
  • - specifies the type of data accepted. You need to include the URI and/or MIME type
  • - specifies the intent category accepted. You must include the category, DEFAULT, in the filter if you want a component to receive the intent (except if you’re using the  startActivity() and startActivityForResult() methods)

You can include more than one instance of the action, data, and category elements.

Who can and who can’t: Intent Resolution

The system receives the implicit intent and then compares it to all the app filters of all the apps on the device. It applies three tests:

  • Action test
  • Category test
  • Data test
Where’s the action? The Action test

A filter can have zero or more action elements. To pass, the intent’s action must match one of the filter’s actions.

If the filter does not have an action, then no intents get through.

If the intent does not have an action, it will pass but only if the filter has at least one action.

Categorise it! The Category test

A filter can declare zero or more category elements. To pass, every category in the intent must match a category in the filter.

If the intent does not have a category, it will pass regardless of whether there are any categories in the filter.

Da,da,da, data! The Data test

A filter can declare zero or more data elements.

Each data element can specify:

  • MIME type – the data type of the data being matched. For example text/plain
  • Uri - the URI is structured like this: < scheme>://: (together known as the authority)/. Here’s an example
    • content://za.co.101apps:200/folder/subfolder/etc where:
      • scheme – content:
      • host – za.co.101apps
      • port – 200
      • path – folder/subfolder/etc

As far as the Uri structure is concerned, each attribute is optional but:

  • no scheme then the host is ignored
  • no host then the port is ignored
  • neither scheme nor host then the path is ignored
Will the Intent’s URI make it through the filter?

The intent’s URI is only compared to the URI attributes included in the filter. Here are some examples:

  • scheme only – all intents with matching URI schemes will pass
  • scheme and authority (host plus port) but no path - all intents with matching URI schemes and authorities will pass
  • scheme, authority and path - all intents with matching URI schemes, authorities and paths will pass. Paths can include a wildcard (*)

The data test compares the URI and MIME type of the intent with those of the filter. The comparison follows the following rules:

  • Intents with no URI or MIME type will pass if the filter has no URI or MIME type
  • Intents with a URI but no MIME type will pass if the URI matches the filter URI and the filter has no MIME type
  • Intents with a MIME type but no URI will pass if the filter has the same MIME type and no URI
  • Intents with both MIME types and a URI will pass the MIME type part of the test if the filter has the same MIME type. It will pass the URI part of test if its URI matches the filter URI  or:
    • the intent has a content: URI and the filter has no URI
    • the intent has a file:  URI and the filter has no URI

So what’s in the package? Using the PackageManager

You can use the PackageManager’s methods to find out more about the components on a device. Here are some of the methods that you can use:

  • Query methods – to return all components that accept a particular intent. For example:
    • queryIntentActivities() – lists all activities that match the given intent
    • queryIntentServices() – lists all services that match the given intent
    • queryBroadcastReceivers() – lists all broadcast receivers that match the given intent
  • Resolve methods – lists all the components that will respond to particular intent
    • resolveActivity() – returns activities that can handle the given intent
    • resolveContentProvider() – finds a content provider to handle the intent
    • resolveService – gets the best service to handle the given intent. For more on Services, have a look at the article, All about Services

Pending intents

Pending intents are intents that another app can send on behalf of your app at a later time.

When triggered, pending intents execute the packaged intent as if it had been executed from within your application.

You can use pending intents for:

  • notifications - the system notification manager executes the intent. Check out the series of tutorials on Notifications, You can master notifications. It’s easy!
  • app widgets – the home screen app executes the intent
  • intents to be executed in the future – the system’s alarm manager executes the intent. Want to know more about repeating alarms? Have a look at the tutorial, Scheduling Android’s Repeating Alarms

Have look at our tutorial on intents and intent filters. In it we’ll show you how to:

  • use explicit intents to:
    • start a new activity
    • start an activity to get a result
    • start a service
    • broadcast an intent
    • start a new activity from within a broadcast receiver
  • use implicit intents to:
    • use other app’s components to:
      • send an email
      • pick a contact from the contacts list
      • make a phone call
  • use a pending intent to send a notification
  • use intent filters for:
    • a broadcast receiver
    • an activity

I hope that you have found this tutorial helpful.