IntelliJ and Google Maps

Recently, I decided to jump platforms from Windows Phone to Android.  Frankly, I got sick and tired of being a second class citizen on Windows Phone in terms of app deployments.  My how Android has changed in the years since I left it, it is really something to see and use; fantastic operating system.

So I decided it was time to take my Bathroom Review app to Android, even more necessary as my data connection with the Windows Phone no longer works after being deactivated from my Verizon account.  Now, you would think that it being Google, adding a Google Map would be easy (it certainly is on Windows Phone), well, it isn’t, and even worse, I use IntelliJ and most of the tutorials are focused on Eclipse.  So here is how I got it to work with IntelliJ.

Google Play Services

So the entire library involved in using Google Maps is housed in a separate library called “Google Play Services”.  For starters, just getting the 4.x SDK will NOT give you this library, you have to download it separately from under ‘Extras’.
image

Once you have it installed you have to reference it in a way very similar to how libraries are referenced in iOS, as in project module references.  In IntelliJ this can be somewhat tricky and took me a ton of time to really figure out.  The first step is to import the ‘Google Play Services’ code into your project.  You will find the option to do this by opening the Module Settings dialog for YOUR project and selecting the Modules selection.

Right click on your project and select the Add –> Import Module option (alternatively, you can use the + button).  The library is located at /extras/google/google_play_services/libproject/google-play-services_lib/google-play-services_lib.iml (notice: I am referencing the IML file, this is for IntelliJ, a similar file is referenced in the Eclipse import process.
image

Now this is the important part.  You have to add this as BOTH a module dependency AND a library dependency.  This simply involves clicking the + icon for your module and adding a module dependency:
image

And then doing the same again but this selecting library and selecting Google Play Services as a library.
image

The reason for this is, the module dependency will ensure that certain resources (references in the R class) are available in your project, while the library reference will ensure standard code classes are available.  Personally, I would rather not have to worry about this and I believe Android should just provide this as part of the runtime.  In the end, your screen should look something like this:
image

To ensure that Google Play Services is available, create an activity and create a layout to reference.  In the layout, make sure the following XML is present for the layout:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/map"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:name="com.google.android.gms.maps.MapFragment" />

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

IntelliJ will color red the packages and classes it cannot find, even in XML (as of IntelliJ 12).  If anything is red here, something is wrong with your library reference.  This is also how you bring the Map into a view so the user can interact with it.  One final check, to make sure you have access to the appropriate R class that Play Services will use, attempt to write this line of code.  If you can auto-complete this in IntelliJ your module reference is correct.

com.google.android.gms.R

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

If that works, congrats, your references are golden, you are now halfway through the battle.

Getting an API Key

To use Google Maps you will need an API key from Google.  Getting one is pretty easy.  I am going to assume you already have a Google Developer Account setup (I believe if you have a Google Account you can activate the developer console pretty easily).

To put it simply, you will need to create a Google Project, and associate that with an API key and setup the appropriate services.  I feel like this URL (https://developers.google.com/maps/documentation/android/start#creating_an_api_project) explains the process much better than I can.

Here is a look at my Manifest file to give you an idea of what you need to make sure you have in your file:
image

I am hiding my API Key for obvious reasons, but as you can see there is quite the plethora of permissions which are needed to use Maps.  Assuming everything is go there lets cover a few obscure things that need to be set right.

Open project.properties and ensure the following line exists in the file:

android.library.reference.1=../../android/extras/google/google_play_services/libproject/google-play-services_lib

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Notice that your path might be different than this.  The important thing is that a line like this exists.

Also, and this was the super obscure thing.  Ensure the following text exists in the proguard-project.txt file:

image

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

I’ll be honest, I have no idea what this is doing or why it is necessary.  I got both of these tips from here: http://stackoverflow.com/questions/13696620/google-maps-android-api-v2-authorization-failure

Warning!!

So, I found this out the hard way, at present the emulator is NOT able to load Google Play Services which means the sole way to test this code is with a device.  Why this is the case is beyond me and really made me raise an eyebrow at Google (along with this whole process).  Perhaps this is so new (I only just went back to developing Android seriously) that the emulator hasn’t caught up.  But for whatever the reason, ensure that you are using a device when testing code using Google Maps with Google Play Services.  Additionally, if you start seeing some odd behavior or the Maps aren’t loading, trying uninstall and reinstalling the app on your device.

Conclusion

So this whole process took me about 4-6hrs to figure out, probably would’ve been longer without the help of a few people on the Android-Dev IRC channel.  I am always confused when I find things like this which seem way overcomplicated, especially when they are a part of the vendors business; as Google Maps is in this case.  On Windows Phone, you simply drop the tag down in Windows Phone 8 and that’s it.  I was surprised because usually Google is pretty much on par with Microsoft in terms of making things like this easy.  This combined with my reservations about Android Studio (in particular cause I think Gradle and its integration with AS need a lot of work) have made me a bit reserved about the developer story for Android.

I sincerely hope this helps someone because it was extremely frustrating going through this.  I hope this scenario is better supported with the next release of the Android tools.

Another good blog post about Google Maps: http://www.androidhive.info/2013/08/android-working-with-google-maps-v2/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s