We’ve already seen what are Activities, the most basic pieces of every Android app and today’s topic is associated with it. We’re going to see how to communicate between Activities (or Application Blocks) using Intents.
Android Application Blocks
Android apps are composed of Application Blocks, which are special kind of Android classes consisting several elements bundled together, including:
Everything that comes in such package is coordinated by AndroidManifest.XML file. Especially, in this XML file (or by using various attributes on Activity class) it’s possible to register our Application Block to be “callable” by the others.
We’ll see more details in a while, but generally your app block is “callable” when it can be used by the other apps – probably you’ve already seen Application Chooser screen on your Android phone, e.g. when you wanted to open downloaded movie and the system asked you which video player you want to use. The same can be done with your own app – if you’re developing a dialer app, you can register it to be callable for ACTION_DIAL Activity Action. Then, as soon as any other app uses Intent to make a phone call (which we’ll see in this post), Application Chooser appears and your app will be one of the possible ones to use for making this phone call.
What is an Intent ?
Android system is designed to be loosely-coupled. Moreover, there is a principle of least privilege introduced in system’s architecture. It means that each app has access only to Blocks which it requires to work. Different Blocks don’t know much about each other (even if defined within the same application). Here’s where an Intent comes into play. Application Blocks use Intents to asynchronously communicate with each other.
In general, you can think of an Intent literally – it’s the intent (or a will) to do something. By sending Intents between different components, we can coordinate complex actions such as launching email app to send a message, using Location for obtaining user’s coordinates or navigating between application’s screens.
For me, we can think of Intents and their usage from two perspectives:
- Intent as an intent – a will to do something. In this case, you use Intent to execute some action. When creating a new Intent you need to tell it what you want to do and give it necessary parameters for such operation (e.g. for send email action, you need to provide email address parameter)
- Intent as a message – bidirectional information having sender, recipient and potentially some content. This can be for instance navigating to a new screen (Activity), where sender is the original Activity, recipient is the destination Activity to be opened and the content may consist some parameters to pass between two screens.
We’ll now see those two approaches in details.
Intent as an intent
In order to trigger another (external) action, e.g. camera recording or email sending, we can create an Intent and start a new Activity. Let’s see it by the example I implemented in MoneyBack – I added an additional ListActivity (PeopleListActivity class) which is the list of people added to app’s database. When a person on the list is clicked, I create an Intent in order to call his/her phone number as the following code presents:
What those 4 lines of code do, is when tapping an entry from the list:
it opens the phone dialer app with selected person’s phone number to call:
NOTE: If I had more than one dialer app installed (if the other dialer app has itself registered as receiver for ACTION_DIAL, of course) Android would ask me to choose which app I want to use.
How did that happen? First actually interesting line of code is the following one:
var intent = new Intent(Intent.ActionDial, uri);
It creates a new Intent, giving to it – as we said in the previous paragraph – two things:
- what we want to do – it this case, we set action to Intent.ActionDial, which corresponds to ACTION_DIAL Activity Action
- operation’s parameters – in our case there is just one parameter, which is the phone number in URI format
For each type of Activity Action you want to trigger, you can find what parameters it needs in official Android Documentation.
In the end, we just need to finally start a new Activity with the Intent we just created:
and we’re all done.
Intent as a message
Now, let’s think about our app as a set of Activities, which are loosly-coopled. We have MainActivity class, which represents the main screen of our app. We’ve also built another Activity, which we want to open from the main one. In that case, we already see everything which fits into intent-as-a-message template – two Activities want to “talk” with each other.
In MoneyBack I changed the MainActivity to look as follows:
When clicking on “People Management” button, I’d like another Activity (represented by PeopleActivity class) to open.
In order to achieve that, MoneyBack executes the following code when clicking on the button:
What you can see here, is that we create a new Intent that takes two parameters:
- Context – being the class storing information about current application’s/Activity’s state, from the place where the Intent is created; in our case, we set it to this, which is the calling Activity class reference. Context is our message’s sender
- Type – this is our message’s recipient; in our case it’s the Type of destination Activity we want to start (PeopleActivity)
NOTE: Notice that we have no content provided in that case.
Then we just start the Activity as in the previous example and another screen appears:
If the back button is now pressed, it goes back to previous (calling) Activity. That’s how the Activities stack is built, by the way 😉
Passing additional content using Intent as a message
I mentioned we can also pass some additional data (message’s content) within an Intent. In the above example we didn’t do it, because there is no sense to pass anything from MainActivity to PeopleActivity for now. However, if we’d like to do that, we can add a simple modification to button’s pressing code in MainActivity:
As you see, I used PutExtra method of the Intent class to insert msgContent into Intent’s simple key-value Bundle Dictionary called Extras, using “secret_message” string as a key. Then, in the destination Activity’s OnCreate method we can retrieve such value back using Intent.Extras.GetString (for String data type) method:
This kind of data-passing between Activities using Intent.Extras should be used only for simple, mostly key-value data transferring. There are other methods for passing/storing more complex data in an app or between different applications.
Today we’ve seen what is an Intent, how to use it to trigger external actions such as calling a phone number, sending email etc., but also how to use it to handle navigation between Activities. We’ve also passed key-value data between two Activities using Intent.Extras.
Intent, as well as Activity, is one of the fundamental concepts of Android. It’s essential to know how Intents work, how they relate to Activities, Services (which we’ll also cover one day) and Application Blocks. I hope you’ll find it useful 😉