谷歌地图Android API v2抛出GooglePlayServicesNotAvailableException,过时,SupportMapFragment.getMap()返回null

我正在尝试使用Android支持库将新版Google Maps Android API v2整合到应用程序中。 我已经经历了很多迭代,试图到某个地方工作,现在我已经放弃了,我想我应该在这里问一下。

我转到API控制台,创建了一个项目,为Android启用了Google Maps API v2,根据需要创建了一个调试KEY并将其粘贴到清单上。 没有身份validation问题或类似的事情。 很确定我这样做了。

在我的项目的libs文件夹中,我放了android-support-v4.jar (通过项目右键单击 – > Android->添加支持库…)。 在Eclipse中,我做了File-> Import-> Android->现有的Android Code Into Workspace,并导入了最新的(rev 3)android-sdk / google / google_play_services / libproject / google-play-services_lib。 然后我将它作为依赖库添加到我的项目中(项目右键单击 – >属性 – > Android->将其添加为底部的库依赖项。

在我的清单中,我有:

       ...    

在我的mainview.xml中,我有:

  

现在在MainView.java上我有:

 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 } } 

然后我想我可能需要初始化片段,所以我在设置内容视图后添加了我的onCreate

 //Fragments FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.add(R.id.map, SupportMapFragment.newInstance()); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); transaction.commit(); 

然后我说,也许它不是SupportMapFragment但实际上我应该引用实际的片段,在我的onResume我做了:

 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再次为空。

然后我看到有一个MapsInitializer类,所以我想也许我应该先调用它。

所以我在上面的代码中获取片段之前添加了代码:

 try { MapsInitializer.initialize(this); } catch (GooglePlayServicesNotAvailableException e) { e.printStackTrace(); } 

用这个Logcat报告了警告(第313行是MapsInitializer.initialize(this) ):

 com.google.android.gms.common.GooglePlayServicesNotAvailableException at com.google.android.gms.internal.nc(Unknown Source) at com.google.android.gms.internal.na(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) 

在我的整个尝试过程中,Logcat会报告以下警告:

 Google Play services out of date. Requires 2010100 but found 1013 

这可能是罪魁祸首,但我没有find解决办法。

在这一点上,我没有想法。 我在 这里阅读了几个主题, 这里 ,但没有一个建议解决了这个问题。 对于后者,他们建议不要包括项目依赖项,只包括jar文件。 好吧,无论是使用google-play-services_lib/libs文件夹中的google-play-services_lib/libs还是从该项目导出我自己的jar,都无效。

顺便说一句,我在实际设备(2.3.5和平板电脑3.2)上运行,而不是模拟器。

任何帮助全心全意地赞赏。 🙂

更新:

量子比特下面的解决方案。

到目前为止导出库依赖项,一个不必处理它的简洁方法(这在处理存储库时很痛苦)是使用FatJar并导出google_play_services_lib项目(我没有创建本地副本,因为它更新时我不想重新导入),并在项目中包含tha输出fat jar文件作为另一个jar文件。 注意:当选择要包含在fat jar中的jar文件时,我必须排除annotations.jar文件,因为它已经预先包含并导致重复错误。 现在我所要做的就是在项目的libs文件夹中包含google_play_services_rev_3.jar ,我很高兴。

从Play商店下载并安装最新的Google Play services 。 出于某种原因,我无法通过搜索find它。 通过从文件夹/extras/google/google_play_services/samples/maps的SDK运行示例应用程序,我被提示安装升级并被带到Play商店执行此操作。

如该链接底部所述; http://developer.android.com/google/play-services/setup.html

这里有样本代码来正确处理这个问题;

 int checkGooglePlayServices = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { // google play services is missing!!!! /* Returns status code indicating whether there was an error. Can be one of following in ConnectionResult: SUCCESS, SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, mActivity, 1122).show(); } 

我的项目遇到了同样的问题。 解决方案非常简单,只需处理((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); 可以返回null 。 如果您将处理null则buid-in SupportMapFragment将处理Google Play services out of date. 错误,并将显示您的地图本地化消息和用于更新Google Play服务的按钮,就像@qubz在示例项目中讲述的那样。

样本代码:

 @Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); } /** * Sets up the map if it is possible to do so (ie, the Google Play services APK is correctly * installed) and the map has not already been instantiated.. This will ensure that we only ever * call {@link #setUpMap()} once when {@link #mMap} is not null. * 

* If it isn't installed {@link SupportMapFragment} (and * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to * install/update the Google Play services APK on their device. *

* A user can return to this FragmentActivity after following the prompt and correctly * installing/updating/enabling the Google Play services. Since the FragmentActivity may not have been * completely destroyed during this process (it is likely that it would only be stopped or * paused), {@link #onCreate(Bundle)} may not be called again so we should call this method in * {@link #onResume()} to guarantee that it will be called. */ private void setUpMapIfNeeded() { // Do a null check to confirm that we have not already instantiated the map. if (mMap == null) { // Try to obtain the map from the SupportMapFragment. mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { setUpMap(); } } } /** * This is where we can add markers or lines, add listeners or move the camera. In this case, we * just add a marker near Africa. *

* This should only be called once and when we are sure that {@link #mMap} is not null. */ private void setUpMap() { mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker")); }

结果:

在此处输入图像描述

随着文件伤心

只有在加载基础地图系统并且片段中的基础视图存在时,才能使用getMap()获取GoogleMap。 该类自动初始化地图系统和视图; 但是,当它准备就绪时,您无法保证,因为这取决于Google Play服务APK的可用性。 如果GoogleMap不可用,则getMap()将返回null。 SupportMapFragment