Adding map integration

Maps are another truly cool part of mobile computing. They provide a means of navigation, finding points of interest in an area, as well as supporting many other useful scenarios.

There are two basic approaches to interfacing with maps from an app:

  • Navigate to the existing Android map app showing a point of interest.
  • Integrate with the Google Maps API.

The first option is much easier to implement, whereas the second option allows for tighter integration and control of the maps at the cost of more code and complexity.

We chose to go with the first option for the POIApp example for the following reasons:

  • The second option requires very specific versions of Xamarin.Android binding libraries corresponding to Google Play libraries, which at the time of the writing of this book were difficult to locate and configure
  • It is very difficult to get the second option working inside an emulator, meaning you would have to test and view the results of the code on an actual device, which may not be an option for all readers
  • We would need to dedicate more time than we have available in this chapter to get the second option up and running

Xamarin's website contains articles with all the details required to get the second option working.

Navigating to the map app

To navigate to the map app, we will rely on the Intent class we used earlier in the book; however, rather than specifying the Activity class we want to start, we will specify the type of information we would like to view using a URI. Android contains a registry of apps that can display different types of information and will launch the most appropriate app.

The Android platform defines a set of Intent classes that can be used to launch Google apps on Android devices. The following table summarizes the Intent classes related to locations:

URI

Action

geo:latitude,longitude

This action opens the map application centered at a latitude or longitude.

geo:latitude,longitude?z=zoom

This action opens the map application centered at a latitude or longitude and zoomed to the specified level.

geo:0,0?q=my+street+address

This action opens the map application to the location of a street address.

geo:0,0?q=business+near+city

This action opens the map application and displays the annotated search results.

In our case, we have a street address, latitude and longitude, or both. If the street address is present, we should build the Intent class with it, because this will cause the street address to appear in the map app, making it more user friendly. If the street address is not present, we will build the Intent class using latitude and longitude. The following code shows the logic for building the Intent class:

Android.Net.Uri geoUri;
if (String.IsNullOrEmpty (_addrEditText.Text)) {
  geoUri = Android.Net.Uri.Parse (String.Format("geo:{0},{1}", _poi.Latitude, _poi.Longitude));
}
else {
  geoUri = Android.Net.Uri.Parse (String.Format("geo:0,0?q={0}", _addrEditText.Text));
}

Intent mapIntent = new Intent (Intent.ActionView, geoUri);

Prior to launching the Intent class, we need to be sure there is an app that can handle the Intent class; otherwise, we might end up with an unhandled exception from StartActivity().

Checking for registered map apps

Apps provide information about any capabilities they provide (the Intent classes) in their manifest files as an <intent-filter/> element. Since we are relying on an external map app to display our location for us, we should check to be sure such an app exists on the device we are running on. We accomplish this with a few calls to the PackageManager class. The PackageManager class allows you to retrieve various types of information about the application packages installed on a device. The QueryIntentActivities() method allows you to check if there are any apps available to handle a specific Intent class. The following code demonstrates the use of QueryIntentActivities():

PackageManager packageManager = PackageManager;
IList<ResolveInfo> activities = packageManager.QueryIntentActivities(mapIntent, 0);

if (activities.Count == 0) {
  AlertDialog.Builder alertConfirm = new AlertDialog.Builder (this);
  alertConfirm.SetCancelable (false);
  alertConfirm.SetPositiveButton ("OK", delegate {});
  alertConfirm.SetMessage ("No map app available.");
  alertConfirm.Show ();

}
else
  StartActivity (mapIntent);

Create a MapClicked() event handler, attach it to the mapImageButton, and fill in the logic for building and starting the Intent class.

Run POIApp and test navigating to the map from POI. You will notice that once the map app has been presented with the POI location, you have the option of choosing to navigate to it from your current location.

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

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