Yet Another [à compléter]

Using the New Google Maps With Mono for Android

EDIT 2013-03-21 > This article has generally been supersed by the following sample: MapsAndLocationDemo_v2

The new Google Maps Android library came out a couple days ago and is a much needed improvement on top of the old API (fragments!).

We do not yet have cooked up a nice binding for it but thanks to our existing Java interop support, you can already use a raw version of the library in your code today.

To do so, follow the instructions on the Getting Started page to register your project in the API console. Couple of things here:

  • The package name you have to input is the one specified in MyProject > Options > Android Application > Package name field. Make sure that field begins with a lowercase character for the rest (usually, turn it into myProjecy.MyProject).
  • When input-ing the SHA1 of your certificate, you can find out the one used by Mono for Android debug build by unzipping your MyApp-signed.apk and running the following command keytool -printcert -file META-INF/ANDROIDD.RSA.

When you are setup up, open the Android SDK manager and make sure you have downloaded the Google Play framework (at the bottom in extras). If you have correctly retrieved it, you should have a directory on your system at <android-sdk-location>/extras/google/google_play_services.

In your MonoDevelop solution, create a new Android Java Bindings Library project. Then in <android-sdk-location>/extras/google/google_play_services/libproject/google-play-services_lib, rename the lib directory to bin and put bin + res + AndroidManifest.xml + project.properties into a zip file called GMaps2Project.zip (for instance).

Next step is to add that .zip to your binding project. Right-click on it and ensure Build action is set to LibraryProjectZip.

Make sure you are referencing the Mono.Android.Support.V4 package otherwise it won’t compile. Also set the target framework of your binding project to Android 4.0 (Ice Cream Sandwich) if you want MapFragment.

You can then add that project to your main app project dependency.

Now, in your app’s AndroidManifest.xml, add the following couple of lines:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<permission android:name="myProject.MyProject.permission.MAPS_RECEIVE" android:protectionLevel="signature" />
<uses-permission android:name="myProject.MyProject.permission.MAPS_RECEIVE" />

Replace myProject.MyProject with your application package name (that’s where the fact that the first letter is lowercase is important).

Since the new maps use OpenGL ES for rendering, you need to specify that in your app as a requirement (this values is then used by the Play Store to filter out imcompatible devices). As a child of your <manifest /> element in AndroidManifest.xml, add:

<uses-feature android:glEsVersion="0x00020000" android:required="true"/>

To use the Map fragment in your project, I used an alternative path than specifying the fragment directly and instead used a FrameLayout container so that I could instantiate the map in code which allow you to specify more options:

var manager = this.FragmentManager;
var transaction = manager.BeginTransaction ();
var mapOptions = new GoogleMapOptions ()
	.InvokeRotateGesturesEnabled (false)
	.InvokeCompassEnabled (false)
	.InvokeScrollGesturesEnabled (false)
	.InvokeTiltGesturesEnabled (false);
mapFragment = SupportMapFragment.NewInstance (mapOptions);
transaction.Add (Resource.Id.MapContainer, mapFragment, "map");
transaction.Commit();

Here, I’m using the Fragment infrastructure from the Support.V4 package hence why I’m using SupportMapFragment instead of MapFragment.

If all goes well, you should now be able to use the new Google Maps in your application:

Troubleshooting:

  • If you get deployment issue when uploading your app to device, make sure your package name starts with a lowercase letter.
  • If you don’t get any tiles displaying on the map, fire up DDMS and look for permission denied messages which usually are a sign you didn’t use the right SHA1/package name at the API console stage.
  • If you get compilation error on your binding project, make sure you are referencing the Support.V4 library and are using a recent enough Android target for your app.