Google Maps Android API v2 throws GooglePlayServicesNotAvailableException, out of date, SupportMapFragment.getMap() returns null
android, android-support-library, google-maps, google-maps-android-api-2, google-play-services
Solution
Download and install the latest `Google Play services` from the Play Store. For some reason, I couldn't find it by searching. By running the sample app from the SDK in the folder `/extras/google/google_play_services/samples/maps` I was prompted to install the upgrade and was taken to the Play Store to do that.
Problem
I am trying to incorporate the new Google Maps Android API v2 into an application using the Android Support Library. I've gone through many iteration to try to get somewhere to work and now I have given up and thought I should ask here. I went to the API Console, created a project, enabled Google Maps API v2 for Android, created a debug KEY as required and pasted it on the manifest. No authentication problems or anything like that. Pretty sure I did this right. In my project's `libs` folder I put `android-support-v4.jar` (via project right-click->Android->Add Support Library...). In Eclipse I did File->Import->Android->Existing Android Code Into Workspace and imported the latest (rev 3) of android-sdk/google/google_play_services/libproject/google-play-services_lib. Then I added it as a dependency library to my project (project right-click->Properties->Android->Add it as a library dependency on the bottom. In my manifest I have: ``` <manifest xmlns:android="http://schemas.android.com/apk/res/android" ...> <permission android:name="myapp.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <All the uses-permission required like INTERNET, ACCESS_NETWORK_STATE, WRITE_EXTERNAL_STORAGE, FINE AND COARSE LOCATION, etc> <uses-permission android:name="myapp.permission.MAPS_RECEIVE"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/> <application ...> ... <uses-library android:name="com.google.android.maps" /> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AI..."/> </application> ``` In my mainview.xml I have: ``` <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" class="com.google.android.gms.maps.SupportMapFragment" /> ``` Now on MainView.java I have: ``` import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; public class MainView extends FragmentActivity ... { private GoogleMap mMap; @Override protected void onResume() { ... Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.map); SupportMapFragment mapFragment = (SupportMapFragment)fragment; mMap = mapFragment.getMap(); //PROBLEM: mMap is null here even though mapFragment is not } } ``` Then I thought I probably need to initialize the fragments so I added in my `onCreate` after setting the content view: ``` //Fragments FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.add(R.id.map, SupportMapFragment.newInstance()); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); transaction.commit(); ``` Then I said, maybe it's not `SupportMapFragment` but I actually should refer to the actual fragment, and in my `onResume` I did: ``` Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.map); SupportMapFragment mapFragment = (SupportMapFragment)fragment; //Fragments FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.add(R.id.map, mapFragment); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); transaction.commit(); mMap = mapFragment.getMap(); ``` `mMap` is again null after this. Then I saw there is a `MapsInitializer` class, so I thought maybe I should call that first. So I added the code before getting the fragment in the above code: ``` try { MapsInitializer.initialize(this); } catch (GooglePlayServicesNotAvailableException e) { e.printStackTrace(); } ``` With this Logcat reported the warning (line 313 is the `MapsInitializer.initialize(this)`): ``` com.google.android.gms.common.GooglePlayServicesNotAvailableException at com.google.android.gms.internal.n.c(Unknown Source) at com.google.android.gms.internal.n.a(Unknown Source) at com.google.android.gms.maps.MapsInitializer.initialize(Unknown Source) at myapp.activities.MainView.inflateSelectedViewAndSetData(MainView.java:313) at myapp.activities.MainView.onClick(MainView.java:642) at android.view.View.performClick(View.java:3153) at android.view.View$PerformClick.run(View.java:12148) at android.os.Handler.handleCallback(Handler.java:587) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:152) at android.app.ActivityThread.main(ActivityThread.java:4615) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:491) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) at dalvik.system.NativeStart.main(Native Method) ``` Throughout my attempts Logcat would report the following warning: ``` Google Play services out of date. Requires 2010100 but found 1013 ``` This could be a/the culprit but I found no solution. At this point I am out of ideas. I read several threads here, here, here but none of the suggestions resolved the problem. On the latter they suggest not including the project dependency and just including the jar file. Well, that did not work either using either `google-play-services.jar` from the `google-play-services_lib/libs` folder or exporting my own jar from that project. By the way I am running on an actual device (2.3.5 and a tablet with 3.2), not the emulator. Any help wholeheartedly appreciated. :) UPDATE: The solution is below by qubit. As far exporting the library dependency, a neat way to not have to deal with it (which is a pain when dealing with repositories) is to use FatJar and export the `google_play_services_lib` project (which I DID NOT create a local copy from because when it updates I don't want to re-import), and include tha output fat jar file in your project as another jar file. NOTE: When choosing which jar files to include in the fat jar, I had to exclude the `annotations.jar` file as it was already pre-included and was causing errors for duplication. Now all I have to do is include the `google_play_services_rev_3.jar` in my project's `libs` folder and I am good to go.