Showing posts with label Intents and IntentFilters Tutorial. Show all posts
Showing posts with label Intents and IntentFilters Tutorial. Show all posts

Saturday, September 8, 2012

Intent and IntentFilter Tutorial



        
Android Tutorial on Intents and Intent Filter
            Three of the core components of an Android application - activities, services, and broadcast receivers - are activated through messages, called intents. Intent is a java object contains fields that enables to  connect one component to another component based on the field values .Intent is basically a message to exchange among target components.
                    There are two types of intents 1.Explicit intent 2.Implicit intent
Explicit Intent
Explicit Intentsexplicitly defines the component which should be called by the Android system, by using the Java class as identifier
The following shows an explicit Intent. If that Intent is correctly send to the Android system and the class is accessible, it will start the associated class.
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 intent
Implicit Intents do not directly specify the Android components which should be called. They specify the action which should be performed and optionally an URI which should be used for this action.
            On mobile platform you have lots of tasks in form of activities ,services and broadcast receivers are already provided or build  by someone else for example you want to use “Photo display” or displaying web content these are tasks commonly used in many applications. Intent objects contains the following fields
1.Action 2.cateogory 3.data 4.Extras 5.Flag. When an intent is passed from an Activity by startActivity() method android platform at runtime will select the best qualified Activity to display photo or display web content  and invoke it.This is basically called intent resolution which happens at runtime.
An implicit Intent object are tested against an intent filters (of target components) in three areas

  •  Action
  • Category
  •  Data (both URI and data type)
To be delivered to the target component that owns the filter, it must pass all three tests. If an intent can pass through the filters of more than one activity or service, the user may be asked which component to activate. If no target can be found, an exception is raised
           For example the following tells the Android system to view a webpage. Typically the web browser is registered to this Intent but other component could also register them self to this event.
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
            If these Intents are send to the Android system it searches for all components which are registered for the specific action and the data type.If only one component is found, Android starts this component directly. If several components are identifier by the Android system, the user will get an selection dialog and can decide which component should be used for the Intent.

Action Field
       A string naming the action to be performed. The Intent class defines a number of predefined action constants, including  ACTION_CALL, ACTION_EDIT, ACTION_MAIN,ACTION_SYNC, ACTION_BATTERY_LOW, etc.You can also define your own action strings for activating the components in your application
The action largely determines how the rest of the intent is structured - particularly the data and extras fields - much as a method name determines a set of arguments and a return value.
Data Field
The URI of the data to be acted on and the MIME type of that data.Different actions are paired with different kinds of data specifications. If the action field is ACTION_EDIT, the data field would contain the URI of the document to be
displayed for editing. If the action is ACTION_CALL, the data field would be
a tel: URI with the number to call.If the action is ACTION_VIEW and the data field is an http: URI, the receiving activity would be called upon to download and display whatever data the URI refers to.
Examples of Action/Data Pairs
·         ACTION_VIEW content://contacts/people/1 – Display information about the person whose identifier is "1".
·         ACTION_DIAL content://contacts/people/1 – Display the phone dialer with the person filled in.
·         ACTION_VIEW tel:123 -- Display the phone dialer with the given number filled in.
·         ACTION_DIAL tel:123 --Dial the phone dialer with the given number filled in.
·         ACTION_EDIT content://contacts/people/1 – Edit information about the person whose identifier is "1".
·         ACTION_VIEW content://contacts/people/ -- Display a list of people, which the user can browse through.This example is a typical top-level entry into the Contacts application, showing you the list of people.
Category Field
            A string containing additional information about the kind of component (activity, service, or broadcast receiver) that should handle the intent Any number of category descriptions can be placed in an Intent object  Android provides a set of predefined categories We will see them in the following slide) You can define your own categories
CATEGORY_BROWSABLE - The target activity can be invoked within the browser to display data referenced by a link — for example, an image or an e-mail message.
CATEGORY_GADGET - The activity can be embedded inside of another activity that hosts gadgets
CATEGORY_HOME - This is the home activity, that is the first activity that is displayed when the device boots.
CATEGORY_LAUNCHER - The activity can be the initial activity of a task and is listed in the top-level
application launcher.
CATEGORY_PREFERENCE - The target activity is a preference panel.
The Demonstrative project portrays the working of Intent Filter with three activities with various Intent filter parameters. 
1.Create  Android project with details as listed in table below

Property name
Property value
Project name
SRM_IntentFilterTutorial
Package name
in.ac.srmuniv.intentfiltertutorial
Activity name
IntentFilterActivity.java
Layout xml name
main

2 .Copy the code  to the file main.xml in res/layout folder 
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button android:layout_height="wrap_content"
      android:id="@+id/button1"
      android:text="Select Next Activity"
      android:layout_width="wrap_content">
      </Button>

</LinearLayout>
3 .Copy  the following code to the IntentFilterActivity.java
package  in.ac.srmuniv.intentfiltertutorial;
importandroid.app.Activity;
importandroid.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;

public class IntentFilterActivity extends Activity {
    private Button b1;

       /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        b1 = (Button) findViewById(R.id.button1);
        b1.setOnClickListener(new OnClickListener()
        {
            public void onClick(View v){
            
             // Intent i = new Intent(v.getContext(),TextreadActivity.class);
                Intent i = new Intent(Intent.ACTION_VIEW,null);
               //Intent i = new Intent(Intent.ACTION_VIEW,Uri.parse("tel:123"));
              //i.addCategory("com.nawin");
              //i.addCategory("com.nawin.editable");
              //i.addCategory("com.nawin.readable");
             //i.setData(Uri.parse("http://www.globalmobileacademy.com"));
            
                startActivity(i);              
            }
        });
    }
}
4 .Create Activity Texteditactivity.java under  package com.nawin bind textread.xml  to the activity highlighted code shows you
                                //TexteditActivity,java
package in.ac.srmuniv;

importjava.io.BufferedReader;
importjava.io.InputStreamReader;
import java.net.URL;
importandroid.app.Activity;
importandroid.content.Intent;
import android.net.Uri;
import android.os.Bundle;
importandroid.widget.EditText;

public class TexteditActivity extends Activity {

       @Override
       protected void onCreate(Bundle savedInstanceState) {
              // TODO Auto-generated method stub
              super.onCreate(savedInstanceState);
              setContentView(R.layout.textedit);
              Intent intent = getIntent();
              EditText  text = (EditText) findViewById(R.id.editText1);
              // To get the action of the intent use
              String action = intent.getAction();
              if (action != Intent.ACTION_VIEW) {
                     throw new RuntimeException("Should not happen");
              }
              // To get the data use
             
              Uri data = intent.getData();
              if (data!=null)
              {
                     text.setText(data.toString());
                      URL url;
                     try {
                           url = newURL(data.getScheme(), data.getHost(), data.getPath());
                           BufferedReader rd = new BufferedReader(newInputStreamReader(url.openStream()));
                           String line = "";
                           while ((line = rd.readLine()) != null) {
                                  text.append(line);
                           }

                     } catch (Exception e) {
                           e.printStackTrace();
                     }
              }
              text.setText("You can Edit");
     
       }
}

5. Create textedit.xml in  res/layout folder copy the following xml code
<?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">
    <EditText android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:editable="true"android:text="You can edit">
    </EditText>
</LinearLayout>

6.Create Activity Textreadactivity.java under  package com.nawin bind textread.xml  to the activity highlighted code shows you
                                //TextreadActivity,java
package in.ac.srmuniv;

importandroid.app.Activity;
import android.os.Bundle;

public class TextreadActivity extends Activity {
       @Override
       protected void onCreate(Bundle savedInstanceState) {
              // TODO Auto-generated method stub
              super.onCreate(savedInstanceState);
              setContentView(R.layout.textread);
       }

7. Create textread.xml in res/ layout folder copy the following xml code.
  <?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">
    <EditText android:id="@+id/editText1"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:editable="false"
         android:inputType="none"
         android:text="Non Editable">
    </EditText>
</LinearLayout>
8.Modify the manifest file to add upon entries for the two activities highlighted below.
<?xml version="1.0"encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="in.ac.srmuniv.intentfiltertutorial"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="10" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".IntentFilterActivity"
                  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=".TextreadActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/> 
              <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="com.nawin"/>
                <category android:name="com.nawin.readable"/>
                             
            </intent-filter>
        </activity>
        <activity android:name=".TexteditActivity"
                  android:label="@string/app_name">
            <intent-filter>
                 <action android:name="android.intent.action.VIEW"/>
             <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="com.nawin"/>
                <category android:name="com.nawin.editable"/>
                <data android:scheme="http"/>
             </intent-filter>
        </activity>
    
    </application>

</manifest>

9 .Run the application onthe Android  Emulator. Click the Button
     

        Figure 1                                                                                        Figure 2
10 .  Remove the comment in Line no 27 of  IntentFilterActivity.java
        b1 = (Button) findViewById(R.id.button1);
        b1.setOnClickListener(new OnClickListener()
        {
            public void onClick(View v){
            
             // Intent i = new Intent(v.getContext(),TextreadActivity.class);
               Intent i = new   Intent();//Intent.ACTION_VIEW,Uri.parse("http://www.globalmobileacademy.com"));
               i.setAction(Intent.ACTION_VIEW);
              // i.addCategory("com.nawin");
              // i.addCategory("com.nawin.editable");
              //i.addCategory("com.nawin.readable");                //i.setData(Uri.parse("http://www.srmuniv.ac.in.com"));          
             
                startActivity(i);              
            }
        });
    }
11.Run the application again click “Select next activity “ Button .

Figure 4


12.  Add the following code high lightened  in IntentFilterActivity.java
       b1 = (Button) findViewById(R.id.button1);
        b1.setOnClickListener(new OnClickListener()
        {
            public void onClick(View v){
            
             // Intent i = new Intent(v.getContext(),TextreadActivity.class);
               Intent i = new Intent();//Intent.ACTION_VIEW,Uri.parse("http://www.globalmobileacademy.com"));
               i.setAction(Intent.ACTION_VIEW);
               i.addCategory("com.nawin");
              //i.addCategory("com.nawin.editable");
              //i.addCategory("com.nawin.readable");
              //i.setData(Uri.parse("http://www.srmuniv.ac.in.com"));
            
                startActivity(i);              
            }
        });

    }
 

 13.Run the application again click “Select next activity “ Button 

Figure 6

14 .  Add the following code high lightened  in   IntentFilterActivity.java

         public void onClick(View v){
            
             // Intent i = new Intent(v.getContext(),TextreadActivity.class);
  //            Intent i = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.yahoo.com"));
               Intent i = new  Intent();    
               i.setAction(Intent.ACTION_VIEW);
               i.addCategory("com.nawin");
               i.addCategory("com.nawin.editable");
              //i.addCategory("com.nawin.readable");
               //i.setData(Uri.parse("http://www.globalmobileacademy.com"));
               startActivity(i);              
            }

        });
15.Run the application again click “Select next activity “ Button

Figure 8

16.   Add the following code high lightened  in   IntentFilterActivity.java
           // Intent i = new Intent(v.getContext(),TextreadActivity.class);
              Intent i = new Intent();
               i.setAction(Intent.ACTION_VIEW);
               i.addCategory("com.nawin");
               i.addCategory("com.nawin.editable");
              //i.addCategory("com.nawin.readable");
               i.setData(Uri.parse("http://www.srmuniv.ac.in"));
17.Also add code high lightened  in   TexteditActivity.java
Uri data = intent.getData();
              if (data!=null)
              {
                     text.setText(data.toString());
                      URL url;
                     try {
                           url = newURL(data.getScheme(), data.getHost(), data.getPath());
                           BufferedReader rd = new BufferedReader(newInputStreamReader(url.openStream()));
                           String line = "";
                           while ((line = rd.readLine()) != null) {
                                  text.append(line);
                           }

                     } catch (Exception e) {
                           e.printStackTrace();
                     }
              }

             // text.setText("You can Edit");
18.Modify the AndroidManifestFile.xml as shown below for the texteditActivity 
<activity android:name=".TexteditActivity"
                  android:label="@string/app_name">
            <intent-filter>
                 <action android:name="android.intent.action.VIEW"/>
             <category android:name="android.intent.category.DEFAULT" />
                <category android:name="com.nawin" />
                <category android:name="com.nawin.editable" />
                <data android:scheme="http"/>
             </intent-filter>
        </activity>

19.Run the application again click “Select next activity “ Button 



CODE EXPLANATION

In this example application,  you can see explicitly called Intent directly calls the the target component Textreadactivity which is available in same application.Figure 3 Shows the Textreadactivity screen.
            Intent i = newIntent(v.getContext(),TextreadActivity.class);
As given below  When code was modified with Action field added to the Intent creates an Implicit intent call  (code added  to  IntentfilterActivity,java) as given below.
       Intent i = new Intent(Intent.ACTION_VIEW,null);
    Where we call upon the only Intent filter Action field to pass the test of Intent resolution. We can see many in build and user developed target activities qualify the intent resolution test selected by Android platform at runtime. Figure 4  shows many in build activities such as calendar ,call _setting etc along with   our project components of Intent Filter Tutorial are also listed as choice in dialog box for user to select.
As given below  When code was further  modified with custom Action added with implicit intent call as shown below(code added to code listing from IntentfilterActivity,java )
                Intent i = new Intent(Intent.ACTION_VIEW,null);
             i.setAction("com.nawin");
you can see only two Activities Textreadactivity and Texteditactivity qualify the Intent filter which is from our project IntentFilterTutorial.Figure 6 shows the screen
          As given below  When codes were further  modified with custom Action added with implicit intent call as shown below( code added to code listing from IntentfilterActivity,java Figure 7)
                  Intent i = newIntent(Intent.ACTION_VIEW,null);
              i.setAction("com.nawin");
              i.addCategory("com.nawin.editable");
you can see Android platform narrows down Intent resolution to select TexteditActivity as the selected target.Figure 8shows the TexteditActivity Screen
As given below  When codes were further  modified with data field is also added with implicit intent call as shown below(added code to code listing from IntentfilterActivity,java Figure 10)
        b1 = (Button) findViewById(R.id.button1);
        b1.setOnClickListener(new OnClickListener()
        {
            public void onClick(View v){
            
             // Intent i = new Intent(v.getContext(),TextreadActivity.class);
               Intent i = new Intent();//Intent.ACTION_VIEW,Uri.parse("http://www.globalmobileacademy.com"));
               i.setAction(Intent.ACTION_VIEW);
               i.addCategory("com.nawin");
               i.addCategory("com.nawin.editable");
              //i.addCategory("com.nawin.readable");
               i.setData(Uri.parse("http://www.srmuniv.ac.in"));
                startActivity(i);              
            }

        });
             (added code to code listing from TexteditActivity,java Figure 11)
                 Uri data = intent.getData();
              if (data!=null)
              {
                     text.setText(data.toString());
                      URL url;
                     try {
                           url = newURL(data.getScheme(), data.getHost(), data.getPath());
                           BufferedReader rd = new BufferedReader(newInputStreamReader(url.openStream()));
                           String line = "";
                           while ((line = rd.readLine()) != null) {
                                  text.append(line);
                           }

                     } catch (Exception e) {
                           e.printStackTrace();
                     }
              }
             // text.setText("You can Edit");

(added code to code listing from Androidmanifest,xml Figure 12)
             <data android:scheme="http"/>
You can see that qualified Activity is TexteditActivity  which passed the Intent resolution with  action/data pair of custom Action “com.nawin” and data field