When creating applications on Android we will inevitably need access to the user’s data on the phone. Using this data not only creates a much more engaging experience and gives us data that is relevant to our user, but it also makes the application feel more personal; this helps us guarantee the user will keep the application on their device.
There is a caveat to this principle, however. Data on a users phone is very sensitive and personal to that user, so it is important that we gain clearance from the user to access this data. On Android, we use Intents, that are granted permission by the AndroidManifest.xml file. Intents could be used to access contact information, systems resources, or to simply launch a new activity within the application. All of this needs to be stated before hand so the runtime can be aware of what the application will/could do.
An example of using an Intent is to have the user select a contact from their contact list.
In this example, we are using the Intent class to specify we want to perform a “pick” action on a set of data. The data in this case is the set of data that comprises our contact list. This code will cause a special activity to start that will display our contact list to the user so they can select a single contact. If you run this code, as is, you will get a SecurityException as you are attempting to access restricted data without first clearing it with the runtime. You will need to add the following like to your AndroidManifest.xml file.
Note: these tags are defined immediately following the tag block.
With this in place, you will now be ale to have the user pick their contacts, but even if they do, nothing will happen, because there is nothing listening for the return.
Return to the first block of code and notice our call to startActivityForResult. This is a special call that indicates the activity being launched will be used to return a result. To handle this return action, we need to override the method that will receive the callback:
Lets walk through this code. Once we have established that the return is for the action we want (the activity could start multiple activities for results) and that the action completed successfully, we perform some querying functions to extract the picked contact from the data stream indicated by the URI.
Note: I know there is a way to have the user pick multiple contacts, but I have yet to determine the means to accomplish this. Possibly a custom activity that reads the contact data stream.
This is an example of using Intents to access data on the device that allows the user to not only use your application more effectively, but also gives it a more personal feel.
The above was an example or using a predefined activity to acquire data. Intents can also be used to start other activities in your application.
Ideally, your application will contain a single Activity that acts as a “home page”, allowing launching points off into other parts of the application. It is very inadvisable to maintain your entire application in one activity, though circumstances and features may be dictate otherwise.
The first thing to understand about other activities is they must be registered within the AndroidManifest.xml file. The following code sample illustrates how to add new activities to your application:
Lets walk through this. The name refers to the name of the class within the package. Starting with a “.” will indicate to start at the package root, or where the main activity is located. In this case, I have a class CameraActivity located at the same level as my root activity.
Intent-Filter describes what actions the activity can respond to. In this case, we are saying allow an Intent action with the CameraActivity to initiate the activity CameraActivity, you can almost think of this as an alias for the activity. The “category” describes what type of action is being taken, Default, in this case, means to simply launch the event.
At this point, we have now taken the appropriate steps to allow Android to run our secondary activity, all we have to do know is tell it to do so, using an Intent.
Notice this looks very similar to what we stated above with the exception that instead of passing a standard action (courtesy of the Intent class) we are passing the alias that we specified as the action for the activity. The filter will see this and realize that it can only start the CameraActivity activity.
Because we used the startActivity function above, this new activity is started without the expectation of returning to the previous activity. If you wanted to use the new activity to somehow acquire a value to be used by the first activity, you would use startActivityForResult. And your second activity, would need to indicate that the value had been selecting with the following block of code at the end:
First, we create an intent that contains the data that we wish to pass back to the previous activity. Then we pass the OK result code along with this intent through setResult which will ensure that our onActivityResult function is called once the subsequent call to finish is made and the activity exits.
We can then read this result by processing the incoming intents Bundle:
A quick note here, this is an example application that I was working with and thus you see the magic number (3) in the code above. Ideally, you would use a constant to make this meaningful to the user. In this case, 3 is the request code I passed in when I called startActivityForResult.
Once you have determine what the request code is and thus how you want to handle the result and the application came back ok, you can then grab the extras from incoming Intent, the variable “data” in this case.
So in this posting you learned the basics about Intents. Intents are, like Launchers and Choosers in Windows Phone 7, vital to creating usable, interesting, and valuable applications for your users. They allow you to spread your application out and access valuable data that the user could use with a task.
In Android, there is a lot of security surround their use and the access to the data that they can provide. Always remember to check your LogCat when debugging crashing errors for SecurityExceptions.