1.6. Starting Activities and Sub-Activities
To start an activity use the method startActivity(Intent) if you do not need a return value from the called activity.
If you need some information from the called activity use the method startActivityForResult(). Once the called Activity is finished the method onActivityResult() in the calling activity will be called. If you use startActivityForResult() then the activity which is started is considered a "Sub-Activity
2. Implicit Intents - Opening an URL
The following creates an examle project for calling several implicit intent. The Android system is asked to display a URI and chooses the corresponding application for the right URI. Create a new Android application "opensourzesupport.android.intent.implicit" with the Activity "CallIntents". Create the following view layout.
<?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:id="@+id/Button01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Call browser"
android:onClick="callIntent"></Button>
<Button android:id="@+id/Button02" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Call Someone"
android:width="100px" android:onClick="callIntent"></Button>
<Button android:id="@+id/Button03" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Dial"
android:width="100px" android:onClick="callIntent"></Button>
<Button android:id="@+id/Button04" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Show Map"
android:width="100px" android:onClick="callIntent"></Button>
<Button android:id="@+id/Button05" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Search on Map"
android:width="100px" android:onClick="callIntent"></Button>
<Button android:id="@+id/Button06" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Take picture"
android:width="100px" android:onClick="callIntent"></Button>
<Button android:id="@+id/Button07" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Show contacts"
android:width="100px" android:onClick="callIntent"></Button>
<Button android:id="@+id/Button08" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Edit first contact"
android:width="100px" android:onClick="callIntent"></Button>
</LinearLayout>
To be able to use certain intents you need to register then for
your application. Maintain the following "AndroidManifest.xml".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.opensourzesupport.android.intent.implicit"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".CallIntents"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.CALL_PRIVILEGED"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
</manifest>
Change your activity to the following. We will start the new intent with the method startActivityForResult() which allow us to specify a desired result code. Once the intent is finished the method onActivityResult() is called and you can perform actions based on the result of the activity.
package opensourzesupport.android.intent.implicit;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class CallIntends extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void callIntent(View view) {
Intent intent = null;
switch (view.getId()) {
case R.id.Button01:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.opensourzesupport.blogspot.cxom"));
startActivity(intent);
break;
case R.id.Button02:
intent = new Intent(Intent.ACTION_CALL,
Uri.parse("tel:(+49)12345789"));
startActivity(intent);
break;
case R.id.Button03:
intent = new Intent(Intent.ACTION_DIAL,
Uri.parse("tel:(+49)12345789"));
startActivity(intent);
break;
case R.id.Button04:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("geo:50.123,7.1434?z=19"));
startActivity(intent);
break;
case R.id.Button05:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("geo:0,0?q=query"));
startActivity(intent);
break;
case R.id.Button06:
intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);
break;
case R.id.Button07:
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("content://contacts/people/"));
startActivity(intent);
break;
case R.id.Button08:
intent = new Intent(Intent.ACTION_EDIT, Uri.parse("content://contacts/people/1"));
startActivity(intent);
break;
default:
break;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode == 0) {
String result = data.toURI();
Toast.makeText(this, result, Toast.LENGTH_LONG);
}
}
}
If you start your application you should see an list of buttons and if you press the button, different activities should be performed. Note that you do not specify any specific application.
3. Explicit intents and data transfer between activities
The following demonstrates how you can transfer data between two activities. We will use explicit intents in this example and create two activities. The first activity will call the second one via an explicit intent. This second activity will receive data from the first one via the class "Bundle" which can be retrieved via intent.getExtras().
The second activity can be finished either via the back button on the phone or via the button. The method finish() is performed in this case. In this method you can transfer some data back to the calling activity. THis is possible because we use the method startActivityForResult(). If you start an activity via this method the method onActivity result is called on the calling activity once the called activity is finshed.
Create a new Android application "opensourzesupport.android.intent.explicit" with the Activity "ActivityOne". Change the layout "main.xml" to the following.
<?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"
>
<LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content"
android:layout_height="wrap_content"><TextView android:id="@+id/TextView01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="First Activity. Press button to call second activity"
android:minHeight="60dip" android:textSize="20sp"></TextView></LinearLayout>
<LinearLayout android:id="@+id/LinearLayout02" android:layout_width="wrap_content"
android:layout_height="wrap_content"></LinearLayout>
<Button android:id="@+id/Button01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:onClick="onClick"
android:text="Calling an intent"></Button>
</LinearLayout>
Create the layout "second.xml".
<?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">
<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:id="@+id/TextView01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="First value from Activity 1"></TextView>
<EditText android:text="@+id/EditText01" android:id="@+id/EditText01"
android:layout_width="wrap_content" android:layout_height="wrap_content"></EditText>
</LinearLayout>
<LinearLayout android:id="@+id/LinearLayout02"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:id="@+id/TextView02" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Second Value from Activity one"/>
<EditText android:text="@+id/EditText02" android:id="@+id/EditText02"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</LinearLayout>
<Button android:id="@+id/Button01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:onClick="onClick"
android:text="Finished this activity"></Button>
</LinearLayout>
Create a new activity "ActivityTwo" via the AndroidManifest.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="opensourzesupport.android.intent.explicit"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ActivityOne"
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:label="ActivityTwo" android:name="ActivityTwo"></activity>
</application>
<uses-sdk android:minSdkVersion="9" />
</manifest>
Create the following coding for your two activities. The second activity will be called from the first one, displays the transferred data and if you select the button of the back button on the phone you send some data back tot the calling application.
package opensourzesupport
.android.intent.explicit;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class ActivityOne extends Activity {
private static final int REQUEST_CODE = 10;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onClick(View view) {
Intent i = new Intent(this, ActivityTwo.class);
i.putExtra("Value1", "This value one for ActivityTwo ");
i.putExtra("Value2", "This value two ActivityTwo");
// Set the request code to any code you like, you can identify the
// callback via this code
startActivityForResult(i, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data.hasExtra("returnKey1")) {
Toast.makeText(this, data.getExtras().getString("returnKey1"),
Toast.LENGTH_SHORT).show();
}
}
}
}
package opensourzesupport
.android.intent.explicit;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class ActivityTwo extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.second);
Bundle extras = getIntent().getExtras();
if (extras == null) {
return;
}
String value1 = extras.getString("Value1");
String value2 = extras.getString("Value2");
if (value1 != null && value2 != null) {
EditText text1 = (EditText) findViewById(R.id.EditText01);
EditText text2 = (EditText) findViewById(R.id.EditText02);
text1.setText(value1);
text2.setText(value2);
}
}
public void onClick(View view) {
finish();
}
@Override
public void finish() {
Intent data = new Intent();
data.putExtra("returnKey1", "Swinging on a star. ");
data.putExtra("returnKey2", "You could be bettern then you are. ");
setResult(RESULT_OK, data);
super.finish();
}
}