Google Maps Android API v2抛出GooglePlayServicesNotAvailableException,过期,SupportMapFragment.getMap()返回null

我正在尝试使用Android支持库将新版Google Maps Android API v2整合到应用程序中。 我已经经历了许多次迭代,试图find工作的地方,现在我已经放弃了,并认为我应该问这里。

我去了API控制台,创build了一个项目,启用Android版Google Maps API v2,根据需要创build了一个debugging密钥,并将其粘贴到清单上。 没有authentication问题或类似的东西。 很确定我做对了。

在我的项目的libs文件夹中,我把android-support-v4.jar (通过项目右键单击 – > Android->添加支持库…)。 在Eclipse中,我做了文件 – >导入 – > Android->现有的Android代码进入工作区,并导入最新的(rev 3)android-sdk / google / google_play_services / libproject / google-play-services_lib。 然后我把它作为一个依赖库添加到我的项目(项目右键单击 – >属性 – > Android->添加它作为一个库依赖关系的底部。

在我的清单中,我有:

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

在我的mainview.xml中我有:

 <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" /> 

现在在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 

这可能是一个罪魁祸首,但我找不到解决办法。

在这一点上,我没有想法。 我在 这里阅读了几个主题, 在这里 ,但没有任何build议可以解决问题。 在后者,他们build议不包括项目依赖项,只包括jar文件。 那么,这不工作要么从google-play-services_lib/libs文件夹的google-play-services_lib/libs或导出我自己的jar从该项目。

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

任何帮助,衷心感激。 🙂

更新:

下面的解决scheme是qubit。

至于导出库依赖关系,一个简单的方法不必处理它(这是处理存储库时,这是一个痛苦)是使用FatJar和导出google_play_services_lib项目(我不创build本地副本,因为当它更新我不想重新导入),并将你的项目中输出的fat jar文件包含为另一个jar文件。 注意:当select哪个jar文件包含在fat jar中时,我必须排除annotations.jar文件,因为它已经被预先包含并导致重复错误。 现在我所要做的就是将google_play_services_rev_3.jar包含在我的项目的libs文件夹中,我很高兴。

Solutions Collecting From Web of "Google Maps Android API v2抛出GooglePlayServicesNotAvailableException,过期,SupportMapFragment.getMap()返回null"

从Play商店下载并安装最新的Google Play services 。 出于某种原因,我无法通过searchfind它。 通过在文件夹/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();方法很简单((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); 可以返回null 。 如果您将处理null则构build的SupportMapFragment将处理Google Play services out of date. 错误,并会显示地图本地化的消息和更新的Google Play服务的button就像这样@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. * <p> * 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. * <p> * 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. * <p> * 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")); } 

结果:

在这里输入图像说明

作为文件伤心

GoogleMap只能在底层地图系统加载并且片段中的底层视图存在的情况下使用getMap()获取。 这个类自动初始化地图系统和视图; 但无法保证,因为这取决于Google Play服务APK的可用性。 如果GoogleMap不可用,则getMap()将返回null。 SupportMapFragment