studio services play mapview google gms failed example android google-maps android-support-library google-play-services google-maps-android-api-2

services - google maps api key android



La API de Android de Google Maps v2 genera GooglePlayServicesNotAvailableException, desactualizado, SupportMapFragment.getMap() devuelve null (3)

Estoy tratando de incorporar el nuevo Google Maps Android API v2 en una aplicación que utiliza la biblioteca de soporte de Android. He pasado por muchas iteraciones para tratar de llegar a algún lugar para trabajar y ahora me he rendido y pensé que debería preguntar aquí.

Fui a la Consola de API, creé un proyecto, habilité la API de Google Maps v2 para Android, creé una CLAVE de depuración según fuera necesario y la pegué en el manifiesto. No hay problemas de autenticación ni nada de eso. Bastante seguro de que hice esto bien

En la carpeta libs mi proyecto puse android-support-v4.jar (a través del proyecto, android-support-v4.jar derecho-> Android-> Agregar biblioteca de soporte ...). En Eclipse hice Archivo-> Importar-> Android-> Código de Android existente en Workspace e importé el último (rev 3) de android-sdk / google / google_play_services / libproject / google-play-services_lib. Luego lo agregué como una biblioteca de dependencias a mi proyecto (proyecto, haga clic con el botón derecho del mouse en-> Propiedades-> Android-> Agregarlo como una dependencia de la biblioteca en la parte inferior.

En mi manifiesto tengo:

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

En mi mainview.xml tengo:

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

Ahora en MainView.java tengo:

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

Entonces pensé que probablemente necesitaba inicializar los fragmentos, así que agregué en mi onCreate después de configurar la vista de contenido:

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

Entonces dije, tal vez no es SupportMapFragment pero en realidad debería referirme al fragmento real, y en mi onResume lo hice:

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 vuelve a ser nulo después de esto.

Luego vi que hay una clase de MapsInitializer , así que pensé que tal vez debería llamar a eso primero.

Así que agregué el código antes de obtener el fragmento en el código anterior:

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

Con este Logcat notificó la advertencia (la línea 313 es el 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)

A lo largo de mis intentos, Logcat reportaría la siguiente advertencia:

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

Esto podría ser un culpable, pero no encontré ninguna solución.

En este punto ya no tengo ideas. Leí varios hilos here , here , here , pero ninguna de las sugerencias resolvió el problema. En este último, sugieren no incluir la dependencia del proyecto y simplemente incluir el archivo jar. Bueno, eso no funcionó ni usando google-play-services.jar de la carpeta google-play-services_lib/libs ni exportando mi propio jar de ese proyecto.

Por cierto, estoy ejecutando un dispositivo real (2.3.5 y una tableta con 3.2), no el emulador.

Cualquier ayuda sinceramente apreciada. :)

ACTUALIZAR:

La solución está abajo por qubit.

Al exportar la dependencia de la biblioteca, una buena manera de no tener que lidiar con ella (lo cual es una molestia cuando se trata de repositorios) es usar FatJar y exportar el proyecto google_play_services_lib (del cual NO google_play_services_lib una copia local porque cuando se actualiza No quiero volver a importar), e incluir el archivo fat jar de salida en su proyecto como otro archivo jar. NOTA: Al elegir los archivos jar para incluir en el archivo fat, tuve que excluir el archivo annotations.jar porque ya estaba pre-incluido y causaba errores para la duplicación. Ahora todo lo que tengo que hacer es incluir google_play_services_rev_3.jar en la carpeta libs mi proyecto y estoy listo.


Descarga e instala los últimos Google Play services de Google Play services desde Play Store. Por alguna razón, no pude encontrarlo buscando. Al ejecutar la aplicación de muestra desde el SDK en la carpeta /extras/google/google_play_services/samples/maps me /extras/google/google_play_services/samples/maps que instale la actualización y me llevaron a Play Store para hacer eso.


Tuve el mismo problema en mi proyecto. La solución es muy simple, solo maneja la posibilidad de que ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); Puede devolver null . Si manejará null el buzón de entrada SupportMapFragment manejará los Google Play services out of date. error y le mostrará el mensaje y el mapa localizados en el mapa para actualizar el Servicio de Google Play así como @qubz está informando en el proyecto de muestra.

Código de la muestra:

@Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); } /** * Sets up the map if it is possible to do so (i.e., 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")); }

Y el resultado:

Como documentación triste

Un GoogleMap solo se puede adquirir utilizando getMap () cuando se carga el sistema de mapas subyacente y existe la vista subyacente en el fragmento. Esta clase inicializa automáticamente el sistema de mapas y la vista; sin embargo, no se puede garantizar cuándo estará listo porque esto depende de la disponibilidad de los servicios de Google Play APK. Si un GoogleMap no está disponible, getMap () devolverá un valor nulo. SupportMapFragment


como se describe en la parte inferior de ese enlace; http://developer.android.com/google/play-services/setup.html

y aquí viene el código de ejemplo para manejar esto correctamente;

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(); }