Intent

Android Intents and Intent Filters Example

An Android Intent is a “message object” that its purpose is to activate a component of an application (activity, service or broadcastreceiver). Intents allow you to interact with components that belong either at the same application or outside that application. It is an abstract description of an operation to be performed or announced. The Intent object contains information which is used either from the components that receive that intent or the Android system itself. The primary attributes of information are:

  • Action – action to be executed (for activity or service) or reported (for broadcastreceiver)
  • Data – the data to be proceeded on

but there are also secondary pieces that complete the structure of the Intent object.

In addition, there are two types of Intents. The explicit intent specifies the component that the Android system will activate, so this type is used within an application. On the other hand, the implicit intent defines the action that should be acted and optionally it provides data. This type is used to activate components in other applications. The Android System uses intent filters, in order to find a suitable component to handle the intent. An Intent Filter defines the intent that a component can respond to. Therefore, intent filters advertise the capabilities of a component and delimit the intents that can handle.

In this example, we are going to find out how the Android system reacts if the same intent invokes two activities, how a custom intent invokes an activity using intent filters and how the system reacts if an appropriate component doesn’t exist for the intent.

For this tutorial, we will use the following tools in a Windows 64-bit platform:

  1. JDK 1.7
  2. Eclipse 4.2 Juno
  3. Android SDK 4.4

1. Create a New Android Application Project

Open Eclipse IDE and go to File → New → Project → Android Application Project.

Specify the name of the application, the project and the package and then click Next.

createProjectIntentFilt

In the next window, the “Create Activity” option should be checked. The new created activity will be the main activity of your project. Then press Next button.

IntFiltersProject2

In “Configure Launcher Icon” window you should choose the icon you want to have in your app. We will use the default icon of android, so click Next.

createProject3!

Select the “Blank Activity” option and press Next.

createProject4!

You have to specify a name for the new Activity and a name for the layout description of your app. The .xml file for the layout will automatically be created in the res/layout folder. Then press Finish.

createProject5!

Now that the project is created, you can see the final structure of the project in the image below.

structureIntentFilter

2. Create the layout of the Main Activity

The purpose of this application is to send an sms in to a number that the user fills in. So, we need an EditText for the phone number and three different Buttons for the three different situations we are going to create.

Open res/layout/activity_main.xml and paste the following code to the “activity_main.xml” tab.

activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical" >

   <EditText 
        android:id="@+id/recipient"
   		android:layout_width="fill_parent"
   		android:layout_height="wrap_content"
   		android:hint="@string/number" />
    
   <Button 
        android:id="@+id/sendto_sms"
   		android:layout_width="fill_parent"
   		android:layout_height="wrap_content"
   		android:text="@string/sms1" />

   <Button 
        android:id="@+id/smsintent_sms"
   		android:layout_width="fill_parent"
   		android:layout_height="wrap_content"
   		android:text="@string/sms2" />
   
   <Button 
        android:id="@+id/exception"
   		android:layout_width="fill_parent"
   		android:layout_height="wrap_content"
   		android:text="@string/exception" />

</LinearLayout>

Then, open res/valuesstrings.xml to the “strings.xml” tab and paste the following.

strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">IntentFilterTest</string>
    <string name="action_settings">Settings</string>
    <string name="number">Write a phone number</string>
	<string name="sms1">Send sms with SENDTO</string>
    <string name="sms2">Send sms with SMS_INTENT</string>
    <string name="exception">Exception Condition</string>

</resources>

3. Code the Main Activity

Our application’s aim is to send a sms using Intent object. We are going to show three different situations and for this reason, we are going to define three listeners, that each one corresponds to a button. In the first button we will use ACTION_SENDTO, an action that Android Intent object provides, in order to send something (for instance sms or email). In the second button, we are going to use a custom intent – called com.example.javacodegeeks.SMS_INTENT – putting some extra fields. At the third button, we will use again our custom intent but this time we will try to send an email. Also we use the EditText, where the user gives the phone number of the sms recipient, in order to put it at the data of the Intent.

Open src/com.javacodegeeks.android.intentfiltertest/MainActivity.java and paste the following code.

MainActivity.java:

package com.javacodegeeks.android.intentfiltertest;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity {
	
	private EditText edit;
	
	@Override
	   protected void onCreate(Bundle savedInstanceState) {
	      super.onCreate(savedInstanceState);
	      setContentView(R.layout.activity_main);

	      edit = (EditText) findViewById(R.id.recipient);
	      
	      // Use ACTION_SENDTO action with correct data
	      Button sms1 = (Button) findViewById(R.id.sendto_sms);
	      sms1.setOnClickListener(new View.OnClickListener() {
	         public void onClick(View view) {
	        	 String uri = "smsto:" +  edit.getText().toString();
	        	 Intent i = new Intent(android.content.Intent.ACTION_SENDTO, 
	        	 Uri.parse(uri));
	             startActivity(i);
	         }
	      });

	      // Use our custom SMS_INTENT intent with correct data
	      Button sms2 = (Button) findViewById(R.id.smsintent_sms);
	      sms2.setOnClickListener(new View.OnClickListener() {
	         public void onClick(View view) {
	        	 String uri = "smsto:" + edit.getText().toString();
	        	 Intent i = new Intent("com.example.javacodegeeks.SMS_INTENT", 
	        			 Uri.parse(uri));
	        	 // put extra field
	        	 i.putExtra("from", "javacodegeeks");
	             startActivity(i);
	         }
	      });

	      // Use our custom SMS_INTENT intent with incorrect data
	      Button exception = (Button) findViewById(R.id.exception);
	      exception.setOnClickListener(new View.OnClickListener() {
	         public void onClick(View view) {
	        	String uri = "mailto:" + edit.getText().toString();
	            Intent i = new Intent("com.example.javacodegeeks.SMS_INTENT",
	                    Uri.parse(uri));
	            i.putExtra("from", "javacodegeeks");
	            startActivity(i);
	            
	         }
	      });
	      
	}

}

4. Create a Custom Activity

We should create an activity that would be invoked by intents. This activity will get the data and the extras of the Intent and it will output them in a new layout.

Right click to IntentFilterTest project → New → Class.

Specify the name for the new Class and the package you want to put it. We will name it MySmsActivity and we will put it in the same package as the MainActivity.java file.

MySmsActivity

Then, open src/com.javacodegeeks.android.intentfiltertest/MySmsActivity.java and paste the following code.

MySmsActivity.java:

package com.javacodegeeks.android.intentfiltertest;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;

public class MySmsActivity extends Activity {

	 @Override
	   public void onCreate(Bundle savedInstanceState) {
	      super.onCreate(savedInstanceState);
	      setContentView(R.layout.intent_view);

	      String output = null;
	      TextView dataIntent = (TextView) findViewById(R.id.output_intent);
	    
	      // take the data and the extras of the intent
	      Uri url = getIntent().getData();
	      Bundle extras = getIntent().getExtras();
	      
	      output = url.toString();
	      // if there are extras, add them to the output string
	      if(extras != null){
	    	  output = output+ " from "+ extras.getString("from");
	      }
	      dataIntent.setText(output);
	   }
}

5. Create the layout of the Custom Activity

The layout of the MySmsActivity activity, is a new xml file that contains only a Textview.

Right click to IntentFilterTest project → New → Android XML File.

Specify the name of the file and choose a root element. We are going to name it intent_view and choose LinearLayout, as shown in the image below. Then press Finish.

intent_view

Open res/layout/intent_view.xml to the “intent_view.xml” tab and paste the following code.

intent_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
 	<TextView 
        android:id="@+id/output_intent"
   		android:layout_width="fill_parent"
   		android:layout_height="fill_parent" />

</LinearLayout>

6. Define the Rules for the Intent

A component receives an implicit intent only if it can pass through one of the component’s filters. Therefore, the Android system have to know about the capabilities of the component before activate it, so we define the intent filters in the application’s manifest file (AndroidManifest.xml).

Before the launch of a component, the implicit intent should be tested against the filter in the action, category and data fields. A filter can contain one or more <action> elements and must not be empty, otherwise it will block all intents. The <category> field is optional. If there are more than one, each one must be matched with a category in the intent. Finally, the <data> element can define a URI and a data type that an intent must contain.

Open the AndroidManifest.xml file at the respective xml tab and paste the follownig code.

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javacodegeeks.android.intentfiltertest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.javacodegeeks.android.intentfiltertest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity 
            android:name="com.javacodegeeks.android.intentfiltertest.MySmsActivity" 
            android:label="@string/app_name">
           <intent-filter>
              <action android:name="android.intent.action.SENDTO" />
              <action android:name="com.example.javacodegeeks.SMS_INTENT" />
              <category android:name="android.intent.category.DEFAULT" />
              <data android:scheme="smsto" />
           </intent-filter>
        </activity>
    </application>

</manifest>

As we can see from the above code, the MySmsActivity activity contains some filters. Other activities will be able to invoke the MySmsActivity activity by using either the android.intent.action.SENDTO, or the com.example.javacodegeeks.SMS_INTENT action, since the category is set to android.intent.category.DEFAULT. Also, by using the schema:smsto field, our custom activity expects the data to start with the “smsto:”.

7. Run the Application

To run our application, right click to our project → Run as → Android Application. The AVD will appear with the app loaded.

Lets put a number and press the Send sms with SENDTO button. In the picture below is shown how the system reacts in such situation. The intent invokes two different activities, the default one "android.intent.action.SENDTO and ours com.example.javacodegeeks.SMS_INTENT, as we defined the filter in the AndroidManifest.xml file. So the two options are displayed and the user is going to decide which one to launch.

IntentFilterAVD1

If we choose the Messaging and press “Just once”, the default application will appear with the number filled in (shown in the next picture). Otherwise, our custom activity will launch.

IntentFilterAVD2

Now we go back (back button or ESC) and we are going to press the second button Send sms with SMS_INTENT. Our custom activity will launch, because the filter applies in the AndroidManifest.xml file. So the data and the extras will be displayed in the screen, as shown in the image below.

IntentFilterAVD3

Finally, we go back again and we press the Exception Condition button. The following message will appear.

IntentFilterAVD4

This is happening because there isn’t a defined component that contains a valid filter for that intent. Although the specific intent contains the appropriate action and category, the data doesn’t have the suitable URI (contains mailto instead of smsto).

Download Eclipse Project

This was an example of Intent and Intent Filters in Android. Download the Eclipse Project of this example: IntentFilterTest.zip

Katerina Zamani

Katerina has graduated from the Department of Informatics and Telecommunications in National and Kapodistrian University of Athens (NKUA) and she attends MSc courses in Advanced Information Systems at the same department. Currently, her main academic interests focus on web applications, mobile development, software engineering, databases and telecommunications.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Massimo
Massimo
6 years ago

The code is not working, maybe is it too old?

Back to top button