¿Cómo sé que el mapa está listo para utilizarse cuando se utiliza el SupportMapFragment?

En el método onCreate , estoy utilizando el SupportMapFragment para mostrar un mapa.

  SupportMapFragment fragment = new SupportMapFragment(); getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment).commit(); 

En conjunción con esto, me gustaría añadir un marcador. El problema es cuando la llamada a getMap es nula, ¿cuándo puedo intentarlo de nuevo? ¿Hay un evento en el que pueda inscribirme o mi enfoque sea erróneo?

  mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap(); if(mMap == null) //what do I do here? 

El mapa es, de hecho, mostrar en el teléfono sin embargo, parecen no tener suerte en la obtención de la referencia para agregar marcadores.

ACTUALIZAR:

La razón por la que estaba creando el SupportMapFragment través del constructor es porque el setContentView típico setContentView y no funcionaba. Esto me puso en la situación en la que no podía obtener mi referencia en el método onCreate ya que de hecho estaba creando el SupportMapFragment en ese momento. En una investigación más setContentView , parece que mi problema de setContentView era un subproducto de no tener tanto el jar de Google Play-Services como el módulo / src configurado como parte del proyecto general. Al hacer AMBOS de estos, setContentView ahora funciona y puedo obtener la referencia a través de getMap() como yo esperaría.

Lots.xml …

 <?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> 

LotsActivity.java …

 public class LotsActivity extends FragmentActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lots); GoogleMap mMap; mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap(); if(mMap == null) //this should not occur now } 

EDITAR: getMap está obsoleto ahora

El problema es cuando la llamada a getMap es nula, ¿cuándo puedo intentarlo de nuevo?

Eso depende de la naturaleza del problema.

Si configura el SupportMapFragment través del elemento <fragment> en el diseño, puede llamar a getMap() éxito en onCreate() . Pero, si crea el SupportMapFragment través del constructor, eso es demasiado pronto – GoogleMap todavía no existe. Puede extender SupportMapFragment y anular onActivityCreated() , ya que getMap() está listo para entonces.

Sin embargo, getMap() también puede devolver null para un problema mayor, como Google Play Services no está instalado. Tendrías que usar algo como GooglePlayServicesUtil.isGooglePlayServicesAvailable() para detectar esta condición y tratar con ella como quieras.

Terminé extendiendo la clase SupportMapFragment y usando una devolución de llamada. El código está aquí:

 public class MySupportMapFragment extends SupportMapFragment { public MapViewCreatedListener itsMapViewCreatedListener; // Callback for results public abstract static class MapViewCreatedListener { public abstract void onMapCreated(); } @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); // Notify the view has been created if( itsMapViewCreatedListener != null ) { itsMapViewCreatedListener.onMapCreated(); } return view; } } 

Preferiría haber utilizado una interfaz y anular el método onAttach (actividad), pero en mi caso, no quería que la devolución de llamada regresara a mi MainActivity. Quería que volviera a una instancia de Fragmento. (El GoogleMap era esencialmente un fragmento dentro de un fragmento) configuré la devolución de llamada y cargaba el mapa por programa con esto. Me gustaría tener establecido suMapViewCreatedListener dentro del constructor de MySupportMapFragment, pero se desaconseja usar cualquier otra cosa que constructores sin parámetros.

 itsMySupportMapFragment = new MySupportMapFragment(); MapViewCreatedListener mapViewCreatedListener = new MapViewCreatedListener() { @Override public void onMapCreated() { initPlacesGoogleMapCtrl(); } }; itsMySupportMapFragment.itsMapViewCreatedListener = mapViewCreatedListener; FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.mapFragmentContainer, itsMySupportMapFragment); transaction.addToBackStack(null); transaction.commit(); 

Y luego, cuando recibí la llamada de vuelta, pude conseguir el mapa; No más nulo

 public void initPlacesGoogleMapCtrl() { // Map ready, get it. GoogleMap googleMap = itsMySupportMapFragment.getMap(); // Do what you want... } 

Quisiera comentar la respuesta de CommonsWare pero no tengo suficiente representante para eso. De todos modos, también estaba teniendo este problema que getMap () devolvería null en onActivityCreated. Mi configuración es la siguiente: Tengo MainActivity que contiene un fragmento. En el método onCreateView de ese fragmento creé el SupportMapFragment y lo agregué al fragmento vía childFragmentManager. Me mantuve referencia a la SupportMapFragment y esperaba que me diera el mapa en onActivityCreated que no lo hizo. La solución a ese problema era anular el onActivityCreated del SupportMapFragment pero no el fragmento padre. Lo hice así en onCreateView:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_location, container, false); mMapFragment = new SupportMapFragment() { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mMap = mMapFragment.getMap(); if (mMap != null) { setupMap(); } } }; getChildFragmentManager().beginTransaction().add(R.id.framelayout_location_container, mMapFragment).commit(); return v; } 

El mes pasado (diciembre de 2014) Google dio la solución oficial para este problema. En los servicios de Google Play más recientes (6.5) :

El método getMap () en MapView y MapFragment ahora está obsoleto a favor del nuevo método getMapAsync ().

Con getMapAsync(OnMapReadyCallback callback) puede configurar el oyente para cuando GoogleMap esté listo. Se pasa en devolución de llamada y se proporciona para no ser nulo.

Google proporcionó un código de ejemplo para esto:

 public class MainActivity extends FragmentActivity implements OnMapReadyCallback { ... } 

Y al inicializar el fragmento:

 MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); 

Cuando el mapa esté listo, la devolución de llamada se llamará

 @Override public void onMapReady(GoogleMap map) { map.addMarker(new MarkerOptions() .position(new LatLng(0, 0)) .title("Marker")); } 

También puede utilizar MapsInitializer.initialize(context); Si el problema está relacionado con las bibliotecas que no están siendo inicializadas.

Con los últimos GoogleServices puede utilizar MapFragment.getMapAsync . Directamente desde los documentos

Establece un objeto de devolución de llamada que se activará cuando la instancia de GoogleMap esté lista para utilizarse.

Si mapa == nulo y luego encontrar el mapa

  if (mGoogleMap == null) { SupportMapFragment mapFragment1 = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment1.getMapAsync(this); } 

Y luego llamar a su función onMapReady ();

  • Google Maps v2, desaparecido 'android.support.v4.app.FragmentActivity'
  • OnMarkerClick no funciona (v2)
  • Google Maps no puede agregar referencia a los servicios de Google Play
  • Android googlemaps V2 - Desactivar desplazamiento en panorámica o zoom
  • Android || Obtener la información actual de la ruta de Google Maps
  • Obtener indicaciones para llegar con la API de Google Maps v2
  • Obtenga la latitud y longitud desde el nombre de la dirección dada. NO Geocoder
  • ¿Cómo utilizar MapView en android usando google map V2?
  • Advertencia en Google Map
  • ¿Cómo obtener resultados específicos del país en la API de Google Places para AutocompletePredictions en Android?
  • Mi ubicación y marcador tienen diferentes ubicaciones
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.