Monday, March 03, 2008

Android: Playing with Intents

Android: Playing with Intents



Android Intent Playground 2.0 is described in this post:
Diego Torres Milano's blog: Android Intent Playground 2.0

This document is published at http://docs.google.com/Doc?id=ddwc44gs_31gjdwgxfh

WARNING: Blogspot engine change the link, so you have to cut and paste.

Intents

From Google documentation: “An Intent is a simple message object that represents an ”intention” to do something. For example, if your application wants to display a web page, it expresses its “Intent” to view the URI by creating an Intent instance and handing it off to the system. The system locates some other piece of code (in this case, the Browser) that knows how to handle that Intent, and runs it. Intents can also be used to broadcast interesting events (such as a notification) system-wide.”

An intent is an abstract description of an operation to be performed. It can be used with startActivity to launch an Activity, broadcastIntent to send it to any interested IntentReceiver components, and startService(Intent, Bundle) or bindService(Intent, ServiceConnection, int) to communicate with a background Service.

Intents are one of the most distinctive components of the Android platform. They, among other things, provide the transition between Activities in a similar model as the browser model, where the user navigates from on page to the other and can also go back.

Intent attributes

Intent
primary attributes
action The general action to be performed, such as VIEW_ACTION, EDIT_ACTION, MAIN_ACTION, etc.
data The data to operate on, such as a person record in the contacts database, expressed as a Uri.
secondary attributes
category Gives additional information about the action to execute. For example, LAUNCHER_CATEGORY means it should appear in the Launcher as a top-level application, while ALTERNATIVE_CATEGORY means it should be included in a list of alternative actions the user can perform on a piece of data.
type Specifies an explicit type (a MIME type) of the intent data. Normally the type is inferred from the data itself. By setting this attribute, you disable that evaluation and force an explicit type.
component Specifies an explicit name of a component class to use for the intent. Normally this is determined by looking at the other information in the intent (the action, data/type, and categories) and matching that with a component that can handle it. If this attribute is set then none of the evaluation is performed, and this component is used exactly as is. By specifying this attribute, all of the other Intent attributes become optional.
extras - This is a Bundle of any additional information. This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body, etc.

The best way to explore all of this somewhat complex model is to try it out.

Official Google documentation has some mistakes that turn your exploration a bit more difficult.

For example in http://code.google.com/android/reference/android/content/Intent.html there are some mistakes.

Some examples of action/data pairs are: * VIEW_ACTION content://contacts/1 – Display information about the person whose identifier is “1”. * EDIT_ACTION content://contacts/1 – Edit information about the person whose identifier is “1”. * VIEW_ACTION content://contacts/ – 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. Selecting a particular person to view would result in a new intent { VIEW_ACTION content://contacts/N } being used to start an activity to display that person. * PICK_ACTION content://contacts/ – Display the list of people, allowing the user to browse through them and pick one and return it to the parent activity. This could be used, for example, if an e-mail application wanted to allow the user to pick a person

Should say

  • VIEW_ACTION content://contacts/people/1 – Display information about the person whose identifier is “1”.
  • EDIT_ACTION content://contacts/people/1 – Edit information about the person whose identifier is “1”.
  • VIEW_ACTION 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. Selecting a particular person to view would result in a new intent { VIEW_ACTION content://contacts/people/N } being used to start an activity to display that person.
  • PICK_ACTION content://contacts/people/ – Display the list of people, allowing the user to browse through them and pick one and return it to the parent activity. This could be used, for example, if an e-mail application wanted to allow the user to pick a person

Intent Playground

To explore these relationships, I've made a simple application that allows you to play with Intents and see the results.

This application completes the intent attributes with the information provided and sometimes with other information obtained from it and then invokes the corresponding method.



AndroidIntentPlayground source and binaries can be downloaded from AndroidIntentPlayground.zip.





action

It's an AutoCompleteTextView to select an action from the list (try entering the first letter as a or c. You can also enter the desired action if it's not in the list.

See Intent attributes.

data uri

The data Uri to act on.

See Intent attributes.

type

The MIME type.

See Intent attributes.

intent

Select the kind of method to invoke

  • broadcast: use broadcastIntent(intet)
  • activity: use startActivity(intent)
  • service: use startService(intent, null)
  • resolve: use Intent.resolveActivity()

activity

When the activity is resolved the class name is showed here.

button

Press the button to send the Intent.

Examples

broadcast

Our first example is an intent broadcast. If there's an IntentReceiver which has an Intent that matches our attributes then its onReceiveIntent() method will be invoked. I've explained how to create an IntentReceiver only application in a previous post. If you have installed the SampleIntentReceiver.APK, we can try this example.

Set action to com.codtech.android.training.intent.SAMPLE_ACTION, leave the other fields blank and the intent to broadcast. Press the button and you'll see


Explanation

If we try to resolve the Intent we will receive an error, but broadcasting the intent it reaches our SampleIntentReceiver and the dialog is displayed.

This intent filter in our SampleIntentReceiver AndroidManifest.xml matches

        <receiver android:name=".SampleIntentReceiver">
<intent-filter>
<action android:name="com.codtech.android.training.intent.SAMPLE_ACTION"/>
</intent-filter>
</receiver>

start activity

Set action to android.intent.action.VIEW and data uri to content://contacts/people/1, set intent to activity and the press the button.


Explanation

After pressing the button we will see our first contact displayed.

We hit a bug. It's not possible to obtain the screenshot using DDMS, instead of the contact the previuos activity is displayed.

The intent was resolved to com.google.android.contacts.ViewContactActivity and this activity is invoked by startActivity(intent).

service

You need ApiDemos installed for this to work.

Set action to com.google.android.samples.app.REMOTE_SERVICE, leave the other fields blank, and set intent to service. Press the button.

And the RemoteService will be started.

The triangle in the upper left corner indicates that the service is running.

However, if we try to stop the service, opening the sliding top panel and clicking on SampleRemoteService instead of getting this service activity we'll get LocalServiceController and we cannot stop it. Another bug ?

Workaround: Go to Home, ApiDemosAppServiceRemote Service Controller and the Stop Service.

Explanation

The intent is used as a parameter of startService(intent, null) and the requested service is started if needed.

resolve

Se action to android.intent.action.WEB_SEARCH, enter some strings into data uri, for example cult thinclient. Set intent to resolve and the press the button. We can see that the action is resolved to com.google.android.browser.BrowserActivity. If we further change intent to activity and press the button again, we will see the browser starting and doing the Google search.

Explanation

The activity is resolved to the corresponding class, and if we use this information to start the activity we will see the web browser presenting the search.

Conclusion

This application, Intent Playground, has helped me a lot to discover some interactions between the Android components.

However, I was not able to intercept the intent used by the contacts application when you try to edit its photo. Could it be using an intent instantiated used an explicit class com.google.android.fallback.Fallback ?

Do you have any clue ?

Post a Comment