Chapter 6: Android Intents

Android’s intent system is probably the most powerful platform feature that the Android has. The intents tie apps together internally and externally. The intent system makes it possible for developers to call functionality from the Android platform and from any other installed apps. It also allows your app to provide functionality to other apps.

This chapter explains what Android intents are and where they are used. The goal of this chapter is to give you a good understanding of how the intent mechanism affects Android user interface design. This chapter explains some examples but does not cover the full intent specification and all use cases. I encourage you to see Android documentation for deeper technical information (see http://developer.android.com/reference/android/content/Intent.html).

Intents allow apps to work together

In short, an intent is a technical and formally defined message sent to an application component. The message can be internal in one app or sent between different apps or even between the operating system and apps. An app can, for example, message the operating system that it wants to dial a phone number.

The most powerful implication of the intent mechanism is that the apps are all capable of working together and sharing each other’s functionality in a very easy and seamless way. Any app can ask the platform to identify other apps that provide certain functionality, and then use one of them or let the user pick one.

One of the most common use cases for intents is an app wanting to share something, an image for example. Regardless of whether your app is a photo editor, a camera app, a drawing app, or anything else, it can let the Android system know that it has an image to share. The operating system knows which other installed apps can help your app with this request.

Let’s look at an example. The following sequence of figures illustrates a series of actions by a user, utilizing the functionality of four different apps to produce a picture and then share it to a social network. In Figure 6-1 the user takes a photo with the Android camera app. Next the user shares the photo to an editor app, Skitch, where he adds a text overlay to the photo (see Figure 6-2). Finally, the user shares the completed picture to Twitter (see Figure 6-3).

9781118387351-fg0601.eps

Figure 6-1: User taking a photo with the Android camera app.

Source: Android

9781118387351-fg0602.eps

Figure 6-2: User adding text overlay to the shared picture with Skitch app.

Source: Skitch, copyright 2012 Evernote Corporation

9781118387351-fg0603.eps

Figure 6-3: User sharing the completed picture to Twitter.

Source: Twitter

Noteworthy in this sequence is that the user at no point has to save the picture to a gallery or file system to continue to work with it. The image file is moved seamlessly by the Android operating system without the user having to know about it. The last step, Twitter sharing, is performed by the Twitter app and, therefore, the user doesn’t have to perform a separate login to ensure that everything is ready for sharing.

Using Social Networks and Sharing

Mobile apps and social networks go hand in hand. People love their phones, and they love to share everything they see, hear, and eat to their social network of choice. On some platforms Facebook and Twitter integration has risen to be a sales pitch and a marketing tool. On an Android device, you can share from all apps to any social network that had an Android app from the start, including Google+, LinkedIn, Orkut, and of course Facebook and Twitter. A new social network only has to provide an Android version of their app using the correct intent filters (explained later in this chapter), and they are done. After installing the app, users can share directly from a gallery, all correctly implemented photo apps, postcard apps, drawing tools, or text editors to the new social network. For the same reason, users aren’t tied down to only to the official client app. In Figure 6-4 you see an example of a user wanting to share an image. Note that Seesmic, Plume, Tweet Lanes, TweetDeck, and Twitter are all Twitter clients and the user is free to use any of them for sharing to Twitter.

When building an Android app you don’t have to worry about social network integration—the platform takes care of it for you. You don’t have to pick the apps you think should be supported or build any functionality for sharing to a specific social network. The only thing you need to do is to implement your sharing intents according to the specification. Note that the list of apps shown in Figure 6-4 is automatically provided by the operating system, so you don’t have to build anything even for that. The operating system takes care of everything. Also noteworthy in Figure 6-4 is that it only shows apps that are able to handle image sharing. The user will never see apps in the list that will not know what do with the type of data that is shared.

Now take a look at Figure 6-5. In this figure the user has triggered a similar sharing intent, but this time she is sharing not an image but a URL from her browser. Android’s intent resolution system automatically figures out which apps it should provide in the list. You will take a better look at intent resolution later in this chapter.

Working with Browsers

Browsers are an essential part of smartphones and tablets. They probably are the one of the most used apps of any Android device. The intent system allows your app to hook into them too. Android browsers, at least the ones implemented correctly, use intents to open each link as the user taps it. Typically the intent is handled by the browser itself, but sometimes the target URL could viewed better by another app. An app can tell the operating system that it can handle URLs with certain patterns, for example a domain name. When a user taps a link that matches the pattern, the operating system presents the user with the familiar choice. In Figure 6-6 you see an example of what happens when a user taps an ordinary HTML link that points to Google Play. The Android operating system recognizes that the link is a special case and that a Google Play app could also handle this request, so the operating system lets the user choose the app she prefers to use. In addition to the two browsers the user has installed, the Google Play app is also presented as an option to complete the action.

9781118387351-fg0604.eps

Figure 6-4: The user has selected to share a file from within the Android gallery app. The Android OS then asks the user to pick which app she wants to use to complete the operation.

Source: Android

9781118387351-fg0605.eps

Figure 6-5: The user has selected to share a URL. The Android OS no longer shows image manipulation apps, but only apps that know what to do with a URL.

Source: Android

9781118387351-fg0606.eps

Figure 6-6: The user clicked a link that points to the Android Market in an Android browser. The operating system recognizes that there is another app that can handle the URL and presents the user with an option to select which of the apps should handle the request.

Source: Android

What makes this particularly powerful is that there’s no special syntax required on the website’s side. The website contains a perfectly normal link that would take the user to the Android Market website if the user were using a normal desktop browser or didn’t have the Google Play app installed on their device.

Tip: If your app is an alternative for viewing content that is also available online, you should make sure that it subscribes to URLs that fit the corresponding domain pattern. There really is no reason not to do it. The app is supposed to be a superior way to browse and interact with the content. If it isn’t you should either rethink your app strategy or improve your app.

Note that URL intents do contain the full URL including all parameters. This means that your app can directly open the right content. In the preceding example, selecting the Google Play app would lead the user directly into the correct app page inside the Google Play app. Similarly, a YouTube link opened using the YouTube app will directly play the correct video.

How do Android intents work?

Let’s take a look under the hood and see how Android intents work. Even if you are not interested in the deep technical details, it is useful to get an overview to better understand what is possible and what isn’t. There’s also some terminology that can be useful to know. The examples in this chapter are very basic; if you’re not a developer, you can just jump over them.

Types of Intents

There are two kinds of intents: activity intents and broadcast intents.

Activity intents: Activity intents always have exactly one sender app and one handler app. The handler app can be an activity or a service. Activity intents are divided into two further categories: explicit and implicit intents.

Explicit intents: If an app knows exactly which activity or service class it wants to handle the intent, it can trigger an explicit intent. The intent will be directly handled by the given activity or service and that’s it. This is how apps typically communicate internally. While a very important construct, explicit intents aren’t very interesting when considering user interfaces.

Implicit intents: Implicit intents are used when the triggering app doesn’t know which app will handle the request. The triggering app creates an intent describing what kind of action it wants to be performed and includes data with the intent and sends it to the operating system.

This implicit intent mechanism creates a loosely coupled relationship between the calling app and the responding app. The interface between them is specified but neither of the apps need to know anything about each other. Keeping components loosely coupled will make your app much easier to maintain as changes in other components or other apps won’t break anything as long as the interface stays unchanged. Also being agnostic about the other apps means that apps you didn’t even think about during your app’s development might later provide shared functionality to your app.

Implicit intents are very interesting and relevant from a user interface design point of view. Understanding how to work with them is a must if you want to build great apps for Android.

Broadcast intents: Broadcast intents are, as the name suggests, sent by one app but can be received and handled by many. Activity intents always have only one app sending the intent and only one handling it. But sometimes one-to-one communication isn’t suitable solution. Some events, such as a device’s battery running low on power, might interest more than a single app. For such situations you need broadcasts. Broadcasts use the same intent mechanisms as explicit intents but broadcasts are handled not by activities or services, but by broadcast receivers.

Technical example of sending intents

In this example, you’ll see how to make the example app allow users do more with a postal address. This functionality is widely used in the Android default apps like Android calendar and Google Maps. It is a good example of the power of the intent system. Let’s say that your application has postal address information. It can be a good idea to provide your users with a map view or even with a navigation option to the address. Note that you don’t have to know what the users will do with the address information. It is up to them to pick the app they want.

The great benefit of using intents here is that you don’t have to write any of the map or navigation code into your app, but you can let other apps handle it. Sending this intent is very simple. Take a look at the following code sample. This code can be anywhere, but in this example it is in an activity class. The intent is triggered when users tap the UI button.

sendIntent.setOnClickListener(new View.OnClickListener() {

  @Override

  public void onClick(View v) {

    Uri geoUri = Uri.parse(„geo:0,0?q=“+ addressField.getText().toString());

    Intent mapCall = new Intent(Intent.ACTION_VIEW, geoUri);

    startActivity(mapCall);

  }

});

When the intent is sent, the users will be shown the already familiar app selection dialog box, as shown in Figure 6-7. If the user selects, for example, Google Maps, the app will open and directly display the correct address, as seen in Figure 6-8.

Intent Filters: Actions, Data, and Categories

How does the operating system know which activity, service, or broadcast receiver should receive the intent? How do you know that an intent you send will be handled only by activities that can perform exactly what you want. You are giving control out from your own app to some other application. You must be able to rely on the operating system to take care that you don’t lead your users into trouble.

9781118387351-fg0607.eps

Figure 6-7: The app selection dialog box after the app sends the intent.

Source: Android

9781118387351-fg0608.eps

Figure 6-8: Google Maps opens the sent address.

Source: Google Inc.

Here is where you need to peek under the hood and understand how Androids intent resolution works. There are two main components in the system. Any activity, service, or broadcast receiver can have a set of intent filters associated with them in the application’s manifest file or dynamically in runtime code. The intent then contains an action definition and data field, and possibly categories and some extra data. When the operating system receives an intent, it compares the action, data, and categories with the intent filters of all apps and picks the ones that match.

Actions and categories are simply names. Nothing more complicated there. Data and extra data are a bit more complex. Data is defined either as a URI or a mime type. A URI is composed of two parts separated by a colon. The first part defines the data type or scheme. The second part identifies the data. For example, the URI tel:123456789 means that the data type is tel and the data is 123456789. In intent resolution the meaningful part is the data type.

Android APIs define a number of standard actions, categories, and extra data keys. These standard intent definitions are used throughout the Android platform. Some are triggered by the operating system while others are used by the default apps that ship with the Android system. The standard actions include send (or share), dial a number, call a number, view, and many more.

Table 6-1 shows a list of standard activity actions, and Table 6-2 shows the standard broadcast actions. For a full list of actions used in the Android SDK, see the intent documentation at http://developer.android.com/reference/android/content/Intent.html.

Table 6-1 Android Standard Activity Actions

Action Name

Action Description

ACTION_ANSWER

Handle an incoming phone call.

ACTION_ATTACH_DATA

Indicate that some piece of data should be attached to some other place.

ACTION_CALL

Perform a call to someone specified by the data.

ACTION_CHOOSER

Display an activity chooser, allowing the user to pick what they want to before proceeding.

ACTION_DELETE

Delete the given data from its container.

ACTION_DIAL

Dial a number as specified by the data.

ACTION_EDIT

Provide explicit editable access to the given data.

ACTION_FACTORY_TEST

Main entry point for factory tests.

ACTION_GET_CONTENT

Allow the user to select a particular kind of data and return it.

ACTION_INSERT

Insert an empty item into the given container.

ACTION_MAIN

Start as a main entry point, does not expect to receive data.

ACTION_PICK

Pick an item from the data, returning what was selected.

ACTION_PICK_ACTIVITY

Pick an activity given an intent, returning the class selected.

ACTION_RUN

Run the data, whatever that means.

ACTION_SEARCH

Perform a search.

ACTION_SEND

Deliver some data to someone else.

ACTION_SENDTO

Send a message to someone specified by the data.

ACTION_SYNC

Perform a data synchronization.

ACTION_VIEW

Display the data to the users.

Table 6-2 Android Standard Broadcast Actions

Action Name

Action Description

ACTION_BATTERY_CHANGED

This is a sticky broadcast containing the charging state, level, and other information about the battery.

ACTION_BOOT_COMPLETED

This is broadcast once, after the system has finished booting.

ACTION_PACKAGE_ADDED

A new application package has been installed on the device.

ACTION_PACKAGE_DATA_CLEARED

The user has cleared the data of a package.

ACTION_PACKAGE_REMOVED

An existing application package has been removed from the device.

ACTION_PACKAGE_RESTARTED

The user has restarted a package, and all of its processes have been killed.

ACTION_POWER_CONNECTED

External power has been connected to the device.

ACTION_POWER_DISCONNECTED

External power has been removed from the device.

ACTION_SHUTDOWN

Device is shutting down.

ACTION_TIME_CHANGED

The timezone has changed.

ACTION_TIMEZONE_CHANGED

The time was set.

ACTION_TIME_TICK

The current time has changed.

ACTION_UID_REMOVED

A user ID has been removed from the system.

In addition to data type and action, the operating system looks into category of the intent and the intent filter. In most cases, the only relevant category is the default category. Whenever intents are sent from your code, the operating system automatically adds the default category to the intent. For the same reason you should always add a default category to your intent filter.

Intent categories become relevant only when you want to replace the home screen activity, car dock, or table dock activities. One exception is category launcher. All activities that have an intent filter with launcher category will be displayed in the application launcher.

Intents can also transmit more data than just the URI. Each intent can have extra data fields that are not formally specified and are not part of the intent resolution. The extra fields are related to different actions. Activities handling certain types of actions expect extra data with certain keywords. Some examples of standard extra keys are email, title, text, subject, stream (used in image sharing) and many more. A complete list of standard extras can be found in the Android documentation at http://developer.android.com/reference/android/content/Intent.html.

Technical example of Receiving intents

Receiving intents isn’t technically much more complex than sending them. Let’s use the same example but from the receiving end. Imagine that your app can provide some useful service to users when they want to view an address. This service could, for example, be anything from special navigation instructions, like biking or public transportation, to a novel way of displaying the address information.

Receiving intents need two components. First, you need to add an activity to your manifest file. In the activity entry you must also define the intent filter to let the Android system know what kind of intents your activity can handle. In the following code sample you see how you can define an intent filter to handle actions to view an URI with geo scheme. The geo URI scheme is a formal specification for describing geolocations.

<activity

  android:name=”.intents.ReceiveIntentExampleActivity”

  android:label=”Smashing Android UI” >

   <intent-filter>

     <action android:name=”android.intent.action.VIEW” />

     <category android:name=”android.intent.category.DEFAULT” />

     <data android:scheme=”geo” />

   </intent-filter>

</activity>

9781118387351-ma01.tif Scan the QR code with your Android phone to open the companion app and try out a functional example. Of course, make sure you have the Smashing Android UI companion app installed on your phone first. See the Introduction for more information.

In the activity code you can read the attached geolocation from the intent. In the following example the geolocation URI is read from the intent data and simply displayed as such. In a real app you would have to parse the URI content to perform something meaningful with it.

@Override

protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setTitle(“Receive Intent Example”);

  setContentView(R.layout.receive_intent_example);

  TextView addressText = (TextView) findViewById(R.id.example_address_field);

  addressText.setText(“” + getIntent().getData());

}

Creating your own Actions

You don’t have to settle for the predefined standard actions. Nothing prevents you from creating your own. Maybe you provide a service in your app that could be useful for other developers, or maybe you have multiple apps and you don’t want to build a tight coupling between them.

Your own actions are simply names for actions that you’ve defined. As a general guideline it is good to always prefix your actions with your app’s package name to keep them from getting mixed up with actions defined by others.

The following example of an intent filter definition is for a custom action that was defined by me. If I now would publish this action name—com.androiduipatterns.smashingandroidui.examples.EXAMPLE_ACTION—on my app’s website, other developers could use it to integrate their apps specifically with this activity.

<activity

android:name=”.intents.ReceiveCustomIntentExampleActivity”

android:label=”Smashing Android UI” >

  <intent-filter>

    <action android:name=”com.androiduipatterns       .smashingandroidui.examples.EXAMPLE_ACTION” />

    <category android:name=”android.intent.category.DEFAULT” />

  </intent-filter>

</activity>

Intents are everywhere

Almost everything on Android is triggered using intents. Whenever you start an app from a launcher, you have used an intent that was triggered by the launcher or home screen. In fact, you start the home screen by triggering an intent. If you want to replace your home screen all you need to do is to make another suitable app handle the home screen intent. The Android home screen and app tray is just an app with specific intent filter.

Even the default phone application is started with an intent, and a phone call is dialed with an intent. Both of them can also be implemented by an app. If you want to write an app that replaces the dialer you can do so.

On Android there’s no such thing as the Android browser. Well, strictly speaking there is an app that is called Android Browser, but what I mean is that Android includes multiple browsers on the platform, and you cannot know which one a user is using. Any app that handles URLs can become the user’s default browser by simply implementing an activity with a corresponding intent filter.

The flexibility of the Android platform opens a lot of opportunities for your app, but it also creates challenges like not being able to rely on the user using the default address book, home screen, dialer, or browser.

Intents Versus Third-party APIs

When it comes to sharing, using intents is not the only option you have. Many social networks and other services provide APIs you can use to integrate their functionality directly into your app. While in some cases this is a good way to go, you should evaluate it carefully. In many cases you will have to implement many features that you could otherwise get for free by using the intents. Also, whenever any of the social networks add more functionality, your app will fall behind until you add them to your implementation. If you are using the intents you will get the new features automatically when the client app is updated.

Another big downside of using tight integration is that if the part of the API you’re using requires user authentication you must implement it into your app. You must either ask users for their credentials or open an embedded web view that does the authentication. Either way the user must trust your app. They either give their login credentials to you or authorize your app to perform operations with their account. Would you want to give a random app your Facebook login credentials or authorize it to post to your Facebook wall?

Summary

I hope I have convinced you about the power and flexibility of the intent mechanism. When thinking about your app’s design, take a minute to think how your app could be a more integral part of your user’s device. Is there some functionality you could share with other apps as an intent? Could you use functionality offered by other apps instead of writing them yourself?

This chapter wasn’t intended to teach you the full technical side of intents. For more details about that side of things I recommend checking out Reto Meier’s Professional Android 4 Application Development book (Wiley, 2012) or Google’s Android developer documentation at http://developer.android.com/reference/android/content/Intent.html.

For intents provided by third-party apps, take a look at the Open Intents website at www.openintents.org/ and especially at the intent registry they maintain.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset