Android
|
Modified: |
Resources
http://developer.android.com/guide/topics/ui/notifiers/notifications.html - Status bar notifications
http://www.vogella.de/articles/AndroidIntent/article.html - Source of these examples and much of the discussion.
http://www.bogotobogo.com/Android/android13Intent.html - Another take on intents.
http://www.xtensivearts.com/2010/04/16/episode-11-intents-multi-activity-applications/ - Multiple activities tutorial
Overview
Objects of type "android.content.Intent" are used to send asynchronous messages within an application or between applications.
Intents are used to send or receive data from and to other activities or services and also to broadcast that a certain event has occurred.
Intents are a powerful concept as they allow the creation of loosely coupled applications. Intents can be used to communicate between any installed application component on the device.
An Intent object can contain information for the receiving component. For example if your application calls via an Intent a browser it may send the URL to the browser component. An Intent also contain information for the Android system so that the Android system can determine which component should handle the request.
Implicit vs Explicit Intents
Android supports explicit intents and implicit intents.
Explicit intent names the component, e.g. the Java class which should be called.
Implicit intents ask the system to perform a service without telling the system which Java class should do this service.In constructing an implicit Intent, specify the action which should be performed and optionally an URI which should be used for this action.
For example, one can tell the system to view (action) a webpage (URI). Given an implicit intent to view a webpage, the system would try to find an application registered for this action, e.g. a browser.
Extra data is added to the Intent by key/value pairs.
The following creates an Intent with key/value pairs to perform ACTION_VIEW of the URI "http://www.ius.edu/rwisman".
intent = new Intent( Intent.ACTION_VIEW, Uri.parse("http://www.ius.edu/rwisman"))
To have Android OS locate and start an Activity to perform ACTION_VIEW:
startActivity(intent)
which executes the browser.
The CallIntents activity literally broadcasts a message to any activity that handles ACTION_VIEW requests using either:
startActivity(intent) - which starts the activity defined by the intent or
startActivityForResult(intent, 0) - which starts the activity defined by the intent and, when completed the activity calls back to method onActivityResult().
package edu.ius.rwisman.CallIntents;
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 CallIntents extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
// Executed by button click
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.ius.edu/rwisman"));
startActivity(intent);
break;
case R.id.Button02:
intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);
break;
default:
break;
}
}
@Override
protected 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);
}
}
}
|
| <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="edu.ius.rwisman.CallIntents" 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="13" / <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.CAMERA"></uses-permission> </manifest> |
<?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="Take picture" android:width="100px" android:onClick="callIntent"></Button> </LinearLayout> |
Explicit intents and data transfer between activities

The following demonstrates how to transfer data between two activities.
The example uses explicit intents and two activities.
ActivityOne calls ActivityTwo via an explicit intent.
ActivityTwo receives data from ActivityOne via the class "Bundle", retrieved via intent.getExtras().
ActivityTwo can be finished either via the back button on the phone or via the Finish ActivityTwo button. The method finish() is performed in this case.In the finish() method data can be transferred back to the calling activity.
This is possible because the method startActivityForResult() was used in ActivityOne to call ActivityTwo which causes a callback to onActivityResult once the called activity (ActivityTwo) is finished.
Notice in the AndroidManifest.xml, both ActivityOne and ActivityTwo are defined as activity in order to execute both on the same device.
ActivityOne is visible first, then starts and passes data to ActivityTwo.
ActivityTwo executes and displays data received. When Finish ActivityTwo clicked, it finishes, returning data to ActivityOne.
ActivityOne is no executing and can again execute ActivityTwo.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="equ.ius.rwisman.CallsIntentsExplicit" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="13" /> <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> </manifest> |
| <?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"> <TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ActivityOne. \nPress button for ActivityTwo" android:minHeight="60dip" android:textSize="20sp"/> <Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick" android:text="Call ActivityTwo"/> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ActivityTwo results" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" /> </LinearLayout> |
| <?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 ActivityOne"></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 ActivityOne"></TextView> <EditText android:text="@+id/EditText02" android:id="@+id/EditText02" android:layout_width="wrap_content" android:layout_height="wrap_content"></EditText> </LinearLayout> <Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick" android:text="Finish ActivityTwo"></Button> </LinearLayout> |
ActivityOne creates an Intent to call ActivityTwo explicitly via:Intent i = new Intent(this, ActivityTwo.class)
passes data to ActivityTwo by:
i.putExtra("Value1", "Value one for ActivityTwo ");
i.putExtra("Value2", 42);ActivityTwo returns a result in the callback via the onActivityResult(int requestCode, int resultCode, Intent data):
data.getExtras().getString("returnKey1")
package equ.ius.rwisman.CallsIntentsExplicit;
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;
String activityTwoResult = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onClick(View view) {
Intent intent = new Intent(this, ActivityTwo.class);
intent.putExtra("Value1", "Value one for ActivityTwo ");
intent.putExtra("Value2", 42);
// Set REQUEST_CODE to any value to identify the callback
startActivityForResult(intent, 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();
activityTwoResult = data.getExtras().getString("returnKey1");
}
}
}
public void onResume() {
super.onResume();
if(activityTwoResult==null) return;
TextView tv = (TextView) findViewById(R.id.textView2);
tv.setText(activityTwoResult);
}
}
|
ActivityTwo is called explicitly by ActivityOne, getting the named data values passed in the Intent by:
Bundle extras = getIntent().getExtras();
Retrieving caller data from the Bundle by:
String value1 = extras.getString("Value1");
int value2 = extras.getInt("Value2");and returning values to the caller by:
data.putExtra("returnKey1", "Returned value from ActivityTwo. ");
which ActivityOne accesses in onActivityResult() by:
data.getExtras().getString("returnKey1")
package equ.ius.rwisman.CallsIntentsExplicit;
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 {
@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");
int value2 = extras.getInt("Value2");
if (value1 != 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", "Returned value from ActivityTwo. ");
data.putExtra("returnKey2", "More returned value from ActivityTwo. ");
setResult(RESULT_OK, data);
super.finish();
}
}
|
Registering via Intentfilter
An application can register itself for implicit intents to be executed by other activities making a request specifying an intent filter for the selected event.
Intent filters are typically declared in "AndroidManifest.xml".
An intent filter must specify category, action and data filters.
The example creates an application that registers itself as a browser and displays an image.Testing
Execute the first example, CallIntents, and choose Call browser.



UrlImage, an earlier app that displays an image off the Internet, only requires a modification to the AndroidManifest.xml to register responding to an ACTION_VIEW request from the previous implicit intent.
<action android:name="android.intent.action.VIEW" />
Because UrlImage and the default Web browser are now registered for "android.intent.action.VIEW", executing the CallIntents app, which before executed the Web browser implicitly, gives a choice of which to use.
Recall that the implicit intent example executed an Intent with key/value pairs to perform ACTION_VIEW of the URI "http://www.ius.edu/rwisman".
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.ius.edu/rwisman"))
UrlImage app ignores the intent value but could access by:
Intent intent = getIntent();
Uri data = intent.getData();
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="edu.ius.rwisman.urlImage" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="13" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".UrlImageActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http"/> </intent-filter> </activity> </application> </manifest> |
package edu.ius.rwisman.CallIntents;
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 CallIntents extends Activity {
@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.ius.edu/rwisman"));
startActivity(intent);
break;
case R.id.Button02:
intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);
break;
default:
break;
}
}
@Override
protected 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);
}
}
}
|
Notification Manager - Status Bar notifications
A notification can be placed onto the Android status bar using the notification manager. Opening the notification bar can trigger another activity.
Android provides system services such as NOTIFICATION_SERVICE.The NotificationManager object providing NOTIFICATION_SERVICE can be received via getSystemService(NOTIFICATION_SERVICE).
Configure a Notification and create an intent to call the target activity.
The following uses a PendingIntent which is described in Android Services and PendingIntents. Briefly, a PendingIntent is:A description of an Intent and target action to perform with it. Instances of this class are created with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), getService(Context, int, Intent, int); the returned object can be handed to other applications so that they can perform the action you described on your behalf at a later time.
By giving a PendingIntent to another application, you are granting it the right to perform the operation you have specified as if the other application was yourself (with the same permissions and identity). As such, you should be careful about how you build the PendingIntent: often, for example, the base Intent you supply will have the component name explicitly set to one of your own components, to ensure it is ultimately sent there and nowhere else.
A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.The notification is sent to the same ActivityTwo.java with the same second.xml from an earlier example.
AndroidManifest.xml only unusual change to CreateNotification is adding ActivityTwo activity:
<activity android:label="ActivityTwo" android:name="ActivityTwo"></activity>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="edu.ius.rwisman.CreateNotification" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="13" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".CreateNotification" 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"/> </application> </manifest> |



To create a notification, use two classes: Notification and NotificationManager.
Use an instance of the Notification class to define the properties of the status bar notification, such as the status bar icon, the notification message, and extra settings such as a sound to play. Below uses the default Android icon.
Notification notification = new Notification(R.drawable.icon, "A new notification", System.currentTimeMillis());
The NotificationManager is an Android system service that executes and manages all status bar notifications. The NotificationManager is not instantiated directly.
To give the NotificationManager a Notification, retrieve a reference to the NotificationManager with getSystemService().
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
An Intent defines the activity to execute when the user accepts the notification
Intent intent = new Intent(this, ActivityTwo.class);
Extra data can be passed to and retrieved by the activity as in the explicit intent example:
intent.putExtra("Value1", "Value one for ActivityTwo ");
intent.putExtra("Value2", 42);Retrieve a PendingIntent from this activity that will start a new activity:
PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
PendingIntent - A description of an Intent and target action to perform with it. Instances of this class are created with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), getService(Context, int, Intent, int); the returned object can be handed to other applications to perform the action described on your behalf at a later time. Giving a PendingIntent to another application grants it the right to perform the operation specified as if the other application was yourself (with the same permissions and identity).
Other information about the notification is added for display to user:
notification.setLatestEventInfo(getApplicationContext(),
"This is the title",
"This is the text",
activity);
notification.number += 1;To notify the user, pass the Notification with notify().
notificationManager.notify(0, notification);
package edu.ius.rwisman.CreateNotification;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class CreateNotification extends Activity {
Notification notification = new Notification(R.drawable.icon, "A new notification", System.currentTimeMillis());
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
// Executed by Create Notification button click
public void createNotification(View view) {
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Hide the notification after its selected
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Intent intent = new Intent(this, ActivityTwo.class); // Execute when notification selected
intent.putExtra("Value1", "Value one for ActivityTwo ");
intent.putExtra("Value2", 42);
// Retrieve PendingIntent to start new activity
PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
notification.setLatestEventInfo(getApplicationContext(),
"This is the title", // Displayed when notification icon selected
"This is the text",
activity);
notification.number += 1;
notificationManager.notify(0, notification); // Place notification on bar
}
}
|
Executed when notification selected.
package equ.ius.rwisman.CallsIntentsExplicit;
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 {
@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");
int value2 = extras.getInt("Value2");
if (value1 != 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", "Returned value from ActivityTwo. ");
data.putExtra("returnKey2", "More returned value from ActivityTwo. ");
setResult(RESULT_OK, data);
super.finish();
}
}
|