Launching other apps

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.

How to do it...

Using Intents, we can launch specific activities in other apps:

  1. We can start other activities, such as the default map app, using the 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);
  2. Some activities require that a type be specified instead of a URI; which is done as shown here:
    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); 
  3. If the user has selected a default app for a particular intent, for example when the user chooses to always open pictures in a specific app, the app chooser will not be displayed. We can force the chooser to always be displayed using the following lines of code:
    Intent intent = ...;
    var chooser = Intent.CreateChooser(intent, "Open...");
    StartActivity(chooser);
  4. If we want to get a list of all the available activities for an intent, we use the 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:

  • To make our app visible, we add the [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 })]
  • There is also an option to launch activities with an intent MIME type, which is filtered with the DataMimeType property:
    [IntentFilter(
      new []{ Intent.ActionSend },
      DataMimeType = "text/plain",
      Categories = new[]{ Intent.CategoryDefault })]
  • If we want to launch from an intent with both a MIME type and a data URI, we filter with both properties:
    [IntentFilter(
      new []{ Intent.ActionSend },
      DataScheme = "geo",
      DataMimeType = "text/plain",
      Categories = new[]{ Intent.CategoryDefault })]

How it works...

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.

Note

Implicit intents specify a general action and the Android system displays a list of activities that are able to handle that action.

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.

Note

Implicit intents can start activities using a data URI, a MIME type, or both.

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.

Tip

The activity chooser will not be displayed if either a default app is selected for the intent or none of the apps can handle the intent.

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.

Note

To let Android know that an activity should appear in the chooser, the [IntentFilter] attribute should be applied with parameters specifying what intents it can handle.

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.

There's more...

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.

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

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