Difference between revisions of "Android Explicit Intents – A Worked Example"

From Techotopia
Jump to: navigation, search
(Designing the User Interface Layout for ActivityA)
Line 72: Line 72:
  
 
Once the layout is complete, the user interface should resemble that illustrated in Figure 26-1:
 
Once the layout is complete, the user interface should resemble that illustrated in Figure 26-1:
+
<google>ADSDAQBOX_FLOW</google>
  
 
[[Image:android_explicit_intent_activity1_ui2.png|The user interface for an Android Explicit Intent example]]
 
[[Image:android_explicit_intent_activity1_ui2.png|The user interface for an Android Explicit Intent example]]
  
 
Figure 26-1
 
Figure 26-1
 
  
 
== Creating the Second Activity Class ==
 
== Creating the Second Activity Class ==

Revision as of 19:53, 1 July 2013

PreviousTable of ContentsNext
An Overview of Android IntentsAndroid Implicit Intents – A Worked Example


<google>BUY_ANDROID</google>


The chapter entitled An Overview of Android Intents covered the theory of using intents to launch activities. This chapter will put this theory into practice through the creation of an example application.

The example Android application created in this chapter will demonstrate the use of an explicit intent to launch an activity, including the transfer of data between sending and receiving activities. The next chapter (Android Implicit Intents – A Worked Example) will demonstrate the use of implicit intents.


Contents


Creating the Explicit Intent Example Application

Within the Eclipse environment, create a new Android Application project. Name the project ExplicitIntent, with the appropriate package name and SDK selections. Request the creation of a blank activity and the use of the default launcher icons. On the New Blank Activity screen of the New Android Application wizard, set the Activity Name to ActivityA and the Layout Name to activity_a.

Click Finish to create the new project.

Designing the User Interface Layout for ActivityA

The user interface for ActivityA will consist of a RelativeLayout view containing EditText, TextView and Button views named editText1, textView1 and button1 respectively. Using the Package Explorer, locate the activity_a.xml resource file for ActivityA and double click on it to load it into the Graphical Layout tool. Either design the layout in the Graphical Layout tool, or switch to the XML view and enter the following XML. Note that the “Ask a Question” text displayed on the button view has been assigned to a string resource named ask_text.

If designing the user interface using the graphical tool, be sure to edit the XML afterwards to add the onClick handler for the button1 view:

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

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_above="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="78dp"
        android:inputType="text" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="76dp"
        android:onClick="onClick"
        android:text="@string/ask_text" />
</RelativeLayout>

As covered in An Overview and Example of Android Event Handling, the android:onClick="onClick" resource line in the above XML file uses an alternative way to handle simple click events without having to implement an event listener in the Java code of the activity. By specifying the onClick event type and the method to be called when such an event is detected, it is quick and easy to wire up basic click event handling on a view. Once the onClick() method has been implemented in the ActivityA.java file, it will be called whenever the button is touched by the user.

Once the layout is complete, the user interface should resemble that illustrated in Figure 26-1: <google>ADSDAQBOX_FLOW</google>

The user interface for an Android Explicit Intent example

Figure 26-1


Creating the Second Activity Class

When the “Ask a Question” button is touched by the user, an intent will be issued requesting that a second activity be launched into which an answer can be entered by the user. The next step, therefore, is to create the second activity. Within the Package Explorer panel, right-click on the ExplicitIntent project and select the New -> Class menu option to display the New Java Class dialog.

For the Package: field, click on the Browse… button and select the package name for this application. In the Superclass: field, enter android.app.Activity as the super class.

Finally, enter ActivityB as the name of the new class before clicking on Finish to create the new Activity subclass.

Creating the User Interface for ActivityB

Now that a class file has been created for ActivityB, the next step is to add an XML layout file for the user interface. To achieve this, right-click on the ExplicitIntent project and select the File -> New -> Android XML File menu option. In the resulting dialog, make sure the Resource Type is set to Layout, name the file activity_b.xml and choose the RelativeLayout view as the Root Element. Clicking on the Finish button will create the new resource file.

The only elements that are required for the user interface of the second activity are an EditText, TextView and Button view. With these requirements in mind, load activity_b.xml into the XML editor and modify it as follows, either manually by directly inputting the following XML or visually using the Graphical Layout tool. Note that the input style on the TextView component has been set to Text and that the text on the button has been assigned to a string resource named answer_text:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="86dp"
        android:onClick="onClick"
        android:text="@string/answer_text" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="112dp"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="160dp"
        android:ems="10"
        android:inputType="text" >
        <requestFocus />
    </EditText>
</RelativeLayout>

The completed layout should resemble that illustrated in Figure 26-2:


The user interface for an Android Explicit Intent example

Figure 26-2


Save the file and add the onCreate() method to the ActivityB.java file to ensure that the layout is loaded at runtime:

package com.example.explicitintent;

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

public class ActivityB extends Activity {
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);
    }
}

Adding ActivityB to the Application Manifest File

In order for ActivityA to be able to launch ActivityB using an intent, it is necessary to add an entry for ActivityB to the AndroidManifest.xml file. Locate this file within the Package Explorer panel and double click on it to load it into the Manifest Editor. Within the Manifest Editor, click on the AndroidManifest.xml tab located at the bottom of the editor panel and edit the XML to add the ActivityB entry:

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

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.explicitintent.ActivityA"
            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="ActivityB"
            android:label="ActivityB" >
        </activity>
    </application>

</manifest>

With the second activity created and added to the manifest file, it is now time to write some code in the ActivityA class to issue the intent.

Creating the Intent

The objective for ActivityA is to create and start an intent when the user touches the “Ask Question” button. As part of the intent creation process, the question string entered by the user into the EditText view will be added to the intent object as a key-value pair. When the user interface layout was created for ActivityA, the button object was configured to call a method named onClick() when “clicked” by the user. This method now needs to be added to the ActivityA class ActivityA.java source file as follows:

package com.example.explicitintent;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class ActivityA extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_a);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activitya, menu);
		return true;
	}

    public void onClick(View view) {
    	
		Intent i = new Intent(this, ActivityB.class);
		
		final EditText editText1 = (EditText)  
                        findViewById(R.id.editText1);
		String myString = editText1.getText().toString();
		i.putExtra("qString", myString);
		startActivity(i);
	}	
} 

The code for the onClick() method follows the techniques outlined in An Overview of Android Intents. First, a new Intent instance is created, passing through the current activity and the class name of ActivityB as arguments. Next, the text entered into the EditText object is added to the intent object as a key-value pair and the intent started via a call to startActivity(), passing through the intent object as an argument.

Compile and run the application and touch the “Ask Question” button to launch ActivityB and the back button to return to ActivityA.

Extracting Intent Data

Now that ActivityB is being launched from ActivityA, the next step is to extract the String data value included in the intent and assign it to the TextView object in the ActivityB user interface. This involves adding some code to the onCreate() method of ActivityB in the ActivityB.java source file:

package com.ebookfrenzy.ExplicitIntent;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.TextView;
import android.widget.EditText;

public class ActivityB extends Activity {
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activityb);
        
        Bundle extras = getIntent().getExtras();
		if (extras == null) {
			return;
		}
		
		String qString = extras.getString("qString");
		
		final TextView textView = (TextView) 
                findViewById(R.id.textView1);		
		textView.setText(qString);		
    }
}

Compile and run the application either within an emulator or on a physical Android device. Enter a question into the text box in ActivityA before touching the “Ask a Question” button. The question should now appear on the TextView component in the ActivityB user interface.

Launching ActivityB as a Sub-Activity

In order for ActivityB to be able to return data to ActivityA, ActivityB must be started as a sub-activity of ActivityA. This means that the call to startActivity() in the ActivityA onClick() method needs to be replaced with a call to startActivityForResult(). Unlike the startActivity() method, which takes only the intent object as an argument, startActivityForResult() also requires that a request code be passed through. The request code can be any number value and is used to identify which sub-activity is associated with which set of return data. For the purposes of this example, a request code of 5 will be used, giving us a modified ActivityA class that reads as follows:

public class ActivityA extends Activity {
		
    private static final int request_code = 5;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
    public void onClick(View view) {
    	
		Intent i = new Intent(this, ActivityB.class);
		
		final EditText editText1 = (EditText) 
                      findViewById(R.id.editText1);
		String myString = editText1.getText().toString();
		i.putExtra("qString", myString);
		startActivityForResult(i, request_code);
	}
}

When the sub-activity exits, the onActivityResult() method of the parent activity is called and passed as arguments the request code associated with the intent, a result code indicating the success or otherwise of the sub-activity and an intent object containing any data returned by the sub-activity. Remaining within the ActivityA class source file, this method needs to be implemented as follows:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if ((requestCode == request_code) && 
                     (resultCode == RESULT_OK)) {
		
		TextView textView1 = (TextView) findViewById(R.id.textView1);
			
		String returnString = 
                     data.getExtras().getString("returnData");
			
		textView1.setText(returnString);	
       }
}

The code in the above method begins by checking that the request code matches the one used when the intent was issued and ensuring that the activity was successful. The return data is then extracted from the intent and displayed on the TextView object.

Returning Data from a Sub-Activity

ActivityB is now launched as a sub-activity of ActivityA, which has, in turn, been modified to handle data returned from ActivityB. All that remains is to modify ActivityB to implement the finish() method and to add code for the onClick() method, which is called when the “Submit Answer” button is touched. The finish() method is triggered when an activity exits (for example when the user selects the back button on the device):

public void onClick(View view) {
		finish();
}

@Override
public void finish() {
	Intent data = new Intent();
		
	EditText editText1 = (EditText) findViewById(R.id.editText1);
		
	String returnString = editText1.getText().toString();
	data.putExtra("returnData", returnString);
	
	setResult(RESULT_OK, data);
	super.finish();
}

All that the finish() method needs to do is create a new intent, add the return data as a key-value pair and then call the setResult() method, passing through a result code and the intent object. The onClick() method simply calls the finish() method.

Testing the Application

Compile and run the application, enter a question into the text field on ActivityA and touch the “Ask Question” button. When ActivityB appears, enter the answer to the question and use either the back button or the “Submit Answer” button to return to ActivityA where the answer should appear in the text view object.

Summary

Having covered the basics of intents in the previous chapter, the goal of this chapter has been to work through the creation of an application designed to demonstrate the use of explicit intents together with the concepts of data transfer between a parent activity and sub-activity.

The next chapter will work through an example designed to demonstrate implicit intents in action.


<google>BUY_ANDROID</google>



PreviousTable of ContentsNext
An Overview of Android IntentsAndroid Implicit Intents – A Worked Example