Often, we have to integrate our apps with existing apps on the user's device. This is simply because we will never be able to cover all the possible actions a user may wish to perform.
Using Intents
, we can launch specific activities in other apps:
ActionView
intent and a URI, as follows:var uri = Uri.Parse("geo:37.797786,-122.401855"); var intent = new Intent(Intent.ActionView, uri); StartActivity(intent);
var intent = new Intent(Intent.ActionSend); intent.SetType("text/plain"); intent.PutExtra( Intent.ExtraEmail, new[]{"[email protected]"}); intent.PutExtra( Intent.ExtraSubject, "Email Subject"); intent.PutExtra( Intent.ExtraText, "Email message text here..."); StartActivity(intent);
Intent intent = ...; var chooser = Intent.CreateChooser(intent, "Open..."); StartActivity(chooser);
QueryIntentActivities()
method:Intent intent = ...; IList<ResolveInfo> activities = PackageManager.QueryIntentActivities(intent, 0); foreach (var activity in activities) { var name = activity.ActivityInfo.Name; }
We can also make our activities available in the chooser for other apps to launch:
[IntentFilter]
attribute to our activity and set the DataScheme
property to the scheme of the data URI:[IntentFilter( new []{ Intent.ActionView }, DataScheme = "geo", Categories = new[]{ Intent.CategoryDefault })]
DataMimeType
property:[IntentFilter( new []{ Intent.ActionSend }, DataMimeType = "text/plain", Categories = new[]{ Intent.CategoryDefault })]
[IntentFilter( new []{ Intent.ActionSend }, DataScheme = "geo", DataMimeType = "text/plain", Categories = new[]{ Intent.CategoryDefault })]
Sometimes, we have to send data to, or open an activity from, another app. As we may not know the exact fully qualified name of the activity, or the user may be using an alternative app to handle the action, we have to use a more generic intent. These intents specify a generic action such as "share data" or "show map coordinates". The Android system searches through the list of registered activities to find the ones that can handle the intent. This type of intent is called an implicit intent.
Some implicit intents are created with an action and a URI to be used with the action. An example of an action can be viewing or editing a specified URI. For example, when viewing a map coordinate, we specify the view intent action and then specify the geolocation as the URI.
Another form of implicit intent is to specify the action and the MIME type of the data we wish to view or edit. An example of an action can be sharing some data with a specific type. For example, we can share plain text data using the MIME type "text/plain" or share image data using the "image/jpeg" MIME type.
The data URI can be specified either in the constructor or using the SetData()
method. To specify a MIME type, we use the SetType()
method. If we want to specify both the URI and the MIME type, we use the SetDataAndType()
method. The Android system uses these pieces of data to obtain a list of activities that support interaction with that intent.
Once the system has obtained a list of all the activities that can interact with the intent, it may display the chooser to the user. The chooser allows the user to specify the actual activity that they wish to use. If there is only one activity, or the user has specified a default activity, the system will automatically launch that one. To always display the chooser, we wrap the real intent in a chooser intent, and then display that chooser intent instead of the real intent. The chooser intent is created from the actual intent along with a title, which is to be displayed on the chooser dialog. We use the static CreateChooser()
method on the Intent
type.
If there are no activities that support the intent, then an ActivityNotFoundException
exception will be thrown. We can either catch this exception or first verify that an activity does exist for the intent. To do this, we query the package manager using the QueryIntentActivities()
method. The result is a collection of information regarding the available activities.
We may want one of our activities to appear in the chooser for other apps to launch. We may be creating an app that can handle map coordinates or an app that displays images. To let the Android system know that our app can be used in this manner, we use the [IntentFilter]
attributes on the types that we wish to make available.
The intent filter describes which intents are able to launch this activity. When applying this attribute, we are required to specify the action that can launch this activity. Along with the action, we can specify which URI scheme starts this activity using the DataScheme
property. Also, we can specify what MIME type is supported using the DataMimeType
property. We can use either one or both of these properties to further restrict the intents that can launch this activity.
Finally, we can specify the category that is associated with the component. Categories are used to provide information about what kind of component should handle the intent. If we want our activity to appear in the chooser, we must specify the CategoryDefault
category. Another category that can be used to allow a web browser to launch the activity is the CategoryBrowsable
category. If we apply the CategoryLauncher
category, the activity will appear in the top-level list of apps. This is automatically applied to activities when we set the MainLauncher
property of the [Activity]
attribute.
We can specify custom icons and descriptions for activities that appear in the chooser dialog by setting the Icon
and Label
parameters on the [IntentFilter]
attribute. This is especially useful when a single activity has multiple entry points based on different requirements.
For example, if a single activity can be used to view or to share a data element, we may wish to specify two intent filters. This way we can provide a customized icon and label that more accurately describes the action associated with the entry in the chooser.