Welcome to this review of the Pluralsight course Android Programming with Intents by Jim Wilson
Jim has over 30 years of software engineering experience, with the past 15 years heavily focused on creating mobile device and location-based solutions. He has co-founded multiple software-related startups and has served in a consulting role at several more.
After nearly a decade as a Microsoft Device Application Development MVP, Jim now focuses on developing Android and iOS device applications. Jim’s passion is mentoring software developers. He blogs at hedgehogjim.wordpress.com.
Android Programming with Intents is the 6th course in the Pluralsight learning path for Android, and this month I am reviewing every course in this learning path.
Also in this series:
Part 1 – Android Late Binding and Intents
Part 2 – Android Programming with Intents: Component activation
Part 3 – Android Delegation and Callbacks through PendingIntents
Part 4 – Android Programming with Intents: IntentFilter data tests
Part 5 – Android Platform Features Through Intents
Android Late Binding and Intents
Jim lists the following prerequisites for getting the most out of this course:
- Fundamental knowledge of Java programming
- Experience building Android applications
- Familiarity with Android API levels
- Experience using one of the Android development environments (Eclipse/IntelliJ/Android Studio)
If you are new to Android development, I recommend beginning with one of these earlier courses in the learning path:
Android and Intents
Jim asks why are Intents so important? It’s because it permeates the whole of the Android platform and are the key to so many things we do in Android programming.
Here are just some of the things Intents are used for:
- Displaying Activities
- Communicating with Services
- Notifying applications of system events
- Controlling which Activities appear in the Android program list
The Android approach to program interactivity
Why did Android introduce Intents? It’s very different from what other platforms are using.
The focus of the Android development team was on creating a model that allowed a lot of reusability and extensibility. They architected the Android platform around loose-coupling.
This is because mobile device users tend to be focused on performing tasks rather the focused on any one particular app.
As an example Jim shows a number of different screen which relate to different apps: contact screen, contact details, text messaging, email messaging.
We quickly traverse through all of these screens as part of accomplishing one task and do not think of this as using multiple applications.
The Android platform is also architected around plugability. Jim explains that users have varying needs:
- Users who just want something that works
- Power users who demand lots of features
- Users with various aesthetic preferences
- Users who want different tools for doing the same things at different times
In order to support all of these things, Android has a very plugable architecture.
Jim says traditional approaches don’t do the job well enough. Early-bound libraries, that is binding in a library of how the process works, are no good because they require one app to know all capabilities in advance.
He goes on to say even late-bound libraries are too restrictive, as they still need some knowledge of capabilities and approach. There is a pattern of usage involved that isn’t appropriate for the needs of the modern day mobile user.
The name Intent comes from the need to make one’s intentions known. Once an app has described it’s intentions, its over to the platform to select and activate the best choice for the user.
What is an Intent?
Jim describes Intents as a message structure for activating components.
It exists specifically for component activation, and describes an operation or event of interest.
Intents should not be confused with Android’s generic message class Message as Intents are unrelated to that.
Jim says there are two primary purposes behind Intents:
- Describing a desired operation without type information
- Describing something that has happened
Intents don’t need any type information. They don’t need to know which component they are targeting. How is this possible?
To understand this, Jim explains the four pieces that Intents are made up of:
- Action – operation to perform
- Extras – additional information
- Data – URI and mime type
- Category – subgrouping of the component type
Intents also support data type-specific access. He says it is a little bit confusing, because although Intents don’t need any specific type information, they do use a component name.
This means, if we need to, we can target an Intent at a specific component, and don’t need to specify the four pieces that we usually need. This is a special case scenario for simplifying access to private components.
Jim says often when we are dealing with our own private components, we may use this technique.
However, the full power and reusability of Intents comes from Intents without any type information and so the focus of this course is using Intents without type information.
Routing Intents to a target
Jim explains there are three target types:
- Broadcast Receivers
Each Intent can only target one of these.
In general, components do not directly listen for Intents. Rather, the Android package manager is aware of the Intent and each component’s eligibility.
Later in the course, Jim shows how to dynamically add the information, but in general the Android package manager already has all of the information that it needs.
The Android Package Manager chooses the best matching activity and then activates it.
What does an Intent mean?
Intents can have different meanings:
- Requesting an operation
- Reporting that an event has occurred
Jim says the meaning of an Intent is tied to the target type.
We can think of this as two different scenarios:
Firstly there are Intents that target Services or Activities. Exactly one Service or Activity is selected to receive the Intent. In the special case of there being a tie, the user is prompted to decide which Service or Activity to activate.
The other scenario is an Intent that targets Broadcast Receivers. This specifies that some event has occurred, such as a system being rebooted, or a network change.
All of the matching Broadcast Receivers receive this Intent.
Matching components to Intents
How are Intents matched to components?
Jim says this is where IntentFilters come in. These advertise the capabilties and interests of a given component.
An Intent can have multiple intent filters. Most intent filters are described in the Android manifest. We can also dynamically register certain types of filters, but Jim says this is by far the exception.
IntentFilters have two purposes:
- Determining which components receive a particular Intent
- Describe some capability of the component or feature it desires
Jim says the members of an Intent filter are very much like that of an Intent.
There is an action member, and in this case it is not simply the action but an action test.
We learn that each test describes what the component can handle or belongs to:
- The Action test describes the Intent actions
- The Data test describes URIs and data types
- The Category test describes component sub-groups
Component features and capabilities
IntentFilters are used to advertise features and capabilities.
Android often reviews a component’s IntentFilters passively.
We see an example manifest file with an
intent-filter element inside it. This filter contains an action and category information, and the category is marked as launcher:
<category android:name=”android.intent.category.LAUNCHER” />
Delegating actions with PendingIntents
Jim says PendingIntents are often confusing for developers who are new to Android.
Intents describes the characteristics that we’re interested in. PendingIntents describe the plan of use in advance.
Because the Android platform is built for reusability, an application will often want to take advantage of a feature provided by another application. When we have finished using the feature, the original application needs a way to take control again.
This is the purpose of PendingIntents. They wraps an Intent in an action to perform with it, and they also encapsulate the identity of the creator and the security credentials.
This allows us to use an intermediate feature and then have that feature perform action on our behalf using our credentials.
This may sound dangerous. However we limit what the other application can do and the Android system won’t allow it to exceed its permissions.
A PendingIntent holds:
- The Intent itself
- The planned action
- The identity and security credentials
We use a PendingIntent to delegate a feature off to another component by sending it our PendingIntent.
Once the other application has completed its job, the only thing it can do is to fire the PendingIntent back to our app.
Using PendingIntents we limit the action to specifically what we describe.