Android MapView v2 Pantalla negra

He estado intentando implementar v2 de MapView de Android. Lo conseguí trabajando muy bien con la excepción a este error.

Esto es lo que parece cuando carga la aplicación desde cero … Introduzca aquí la descripción de la imagen

Como puede ver, no hay problemas.

Ahora, cuando presiono el botón "Inicio" y tratar de acceder a la aplicación de la ventana de "aplicaciones recientes" obtengo esto: Introduzca aquí la descripción de la imagen

Y se mantiene así hasta que descarte la aplicación y vuelva a cargarla desde cero.

Aquí hay parte de mi código.

Layout.xml

<LinearLayout android:id="@+id/maps_container" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_marginBottom="100dip" android:layout_marginLeft="10dip" android:layout_marginRight="10dip" android:layout_marginTop="100dip"/> </LinearLayout> 

Actividad:

 public class MyActivity extends BaseActivity { private GoogleMap mMaps; private LinearLayout mMapsContainer; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_layout); mMapsContainer = (LinearLayout) findViewById(R.id.maps_container); mMaps =((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); } @Override public void onPause() { super.onPause(); } @Override public void onResume() { super.onResume(); if (mMaps == null) { mMaps = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); } getSupportFragmentManager().findFragmentById(R.id.map).onResume(); } 

}

BaseActivity:

 public abstract class BaseActivity extends FragmentActivity implements LocationListener, GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener { // A request to connect to Location Services private LocationRequest mLocationRequest; // Stores the current instantiation of the location client in this object private LocationClient mLocationClient; // Handle to SharedPreferences for this app SharedPreferences mPrefs; // Handle to a SharedPreferences editor SharedPreferences.Editor mEditor; boolean mUpdatesRequested = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a new global location parameters object mLocationRequest = LocationRequest.create(); mLocationRequest.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS); // Use high accuracy mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // Set the interval ceiling to one minute mLocationRequest.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS); // Note that location updates are off until the user turns them on mUpdatesRequested = false; // Open Shared Preferences mPrefs = getSharedPreferences(LocationUtils.SHARED_PREFERENCES, Context.MODE_PRIVATE); // Get an editor mEditor = mPrefs.edit(); /* * Create a new location client, using the enclosing class to * handle callbacks. */ mLocationClient = new LocationClient(this, this, this); } @Override public void onStop() { // If the client is connected if (mLocationClient.isConnected()) { stopPeriodicUpdates(); } // After disconnect() is called, the client is considered "dead". mLocationClient.disconnect(); super.onStop(); } @Override public void onPause() { // Save the current setting for updates mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, mUpdatesRequested); mEditor.commit(); super.onPause(); } @Override public void onStart() { super.onStart(); /* * Connect the client. Don't re-start any requests here; * instead, wait for onResume() */ mLocationClient.connect(); } @Override public void onResume() { super.onResume(); // If the app already has a setting for getting location updates, get it if (mPrefs.contains(LocationUtils.KEY_UPDATES_REQUESTED)) { mUpdatesRequested = mPrefs.getBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false); // Otherwise, turn off location updates until requested } else { mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false); mEditor.commit(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // Choose what to do based on the request code switch (requestCode) { // If the request code matches the code sent in onConnectionFailed case LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST : switch (resultCode) { // If Google Play services resolved the problem case Activity.RESULT_OK: break; // If any other result was returned by Google Play services default: // Log the result break; } // If any other request code was received default: // Report that this Activity received an unknown requestCode Log.d(LocationUtils.APPTAG, getString(R.string.unknown_activity_request_code, requestCode)); break; } } private boolean servicesConnected() { // Check that Google Play services is available int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); // If Google Play services is available if (ConnectionResult.SUCCESS == resultCode) { // In debug mode, log the status Log.d(LocationUtils.APPTAG, getString(R.string.play_services_available)); // Continue return true; // Google Play services was not available for some reason } else { // Display an error dialog Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0); if (dialog != null) { ErrorDialogFragment errorFragment = new ErrorDialogFragment(); errorFragment.setDialog(dialog); // errorFragment.show(getSupportFragmentManager(), LocationUtils.APPTAG); } return false; } } public void getAddress(View v) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && !Geocoder.isPresent()) { // No geocoder is present. Issue an error message Toast.makeText(this, R.string.no_geocoder_available, Toast.LENGTH_LONG).show(); return; } if (servicesConnected()) { // Get the current location Location currentLocation = mLocationClient.getLastLocation(); // Start the background task (new GetAddressTask(this)).execute(currentLocation); } } public void startUpdates(View v) { mUpdatesRequested = true; if (servicesConnected()) { startPeriodicUpdates(); } } public void stopUpdates(View v) { mUpdatesRequested = false; if (servicesConnected()) { stopPeriodicUpdates(); } } @Override public void onConnected(Bundle bundle) { if (mUpdatesRequested) { startPeriodicUpdates(); } EventBus.getDefault().post(new EventMessage().new LocationServicesConnected()); } @Override public void onDisconnected() { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { if (connectionResult.hasResolution()) { try { // Start an Activity that tries to resolve the error connectionResult.startResolutionForResult( this, LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST); } catch (IntentSender.SendIntentException e) { e.printStackTrace(); } } else { // If no resolution is available, display a dialog to the user with the error. showErrorDialog(connectionResult.getErrorCode()); } } @Override public void onLocationChanged(Location location) { EventBus.getDefault().post(new EventMessage().new LocationChangedEvent(location)); } private void startPeriodicUpdates() { mLocationClient.requestLocationUpdates(mLocationRequest, this); } private void stopPeriodicUpdates() { mLocationClient.removeLocationUpdates(this); } protected class GetAddressTask extends AsyncTask<Location, Void, String> { // Store the context passed to the AsyncTask when the system instantiates it. Context localContext; // Constructor called by the system to instantiate the task public GetAddressTask(Context context) { // Required by the semantics of AsyncTask super(); // Set a Context for the background task localContext = context; } @Override protected String doInBackground(Location... params) { Geocoder geocoder = new Geocoder(localContext, Locale.getDefault()); // Get the current location from the input parameter list Location location = params[0]; // Create a list to contain the result address List<Address> addresses = null; // Try to get an address for the current location. Catch IO or network problems. try { /* * Call the synchronous getFromLocation() method with the latitude and * longitude of the current location. Return at most 1 address. */ addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1 ); // Catch network or other I/O problems. } catch (IOException exception1) { // Log an error and return an error message Log.e(LocationUtils.APPTAG, getString(R.string.IO_Exception_getFromLocation)); // print the stack trace exception1.printStackTrace(); // Return an error message return (getString(R.string.IO_Exception_getFromLocation)); // Catch incorrect latitude or longitude values } catch (IllegalArgumentException exception2) { // Construct a message containing the invalid arguments String errorString = getString( R.string.illegal_argument_exception, location.getLatitude(), location.getLongitude() ); // Log the error and print the stack trace Log.e(LocationUtils.APPTAG, errorString); exception2.printStackTrace(); // return errorString; } // If the reverse geocode returned an address if (addresses != null && addresses.size() > 0) { // Get the first address Address address = addresses.get(0); // Format the first line of address String addressText = getString(R.string.address_output_string, // If there's a street address, add it address.getMaxAddressLineIndex() > 0 ? address.getAddressLine(0) : "", // Locality is usually a city address.getLocality(), // The country of the address address.getCountryName() ); // Return the text return addressText; // If there aren't any addresses, post a message } else { return getString(R.string.no_address_found); } } /** * A method that's called once doInBackground() completes. Set the text of the * UI element that displays the address. This method runs on the UI thread. */ @Override protected void onPostExecute(String address) { } } /** * Show a dialog returned by Google Play services for the * connection error code * * @param errorCode An error code returned from onConnectionFailed */ private void showErrorDialog(int errorCode) { // Get the error dialog from Google Play services Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog( errorCode, this, LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST); // If Google Play services can provide an error dialog if (errorDialog != null) { // Create a new DialogFragment in which to show the error dialog ErrorDialogFragment errorFragment = new ErrorDialogFragment(); // Set the dialog in the DialogFragment errorFragment.setDialog(errorDialog); // Show the error dialog in the DialogFragment // errorFragment.show(getSupportFragmentManager(), LocationUtils.APPTAG); } } /** * Define a DialogFragment to display the error dialog generated in * showErrorDialog. */ public static class ErrorDialogFragment extends DialogFragment { // Global field to contain the error dialog private Dialog mDialog; /** * Default constructor. Sets the dialog field to null */ public ErrorDialogFragment() { super(); mDialog = null; } /** * Set the dialog to display * * @param dialog An error dialog */ public void setDialog(Dialog dialog) { mDialog = dialog; } /* * This method must return a Dialog to the DialogFragment. */ @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return mDialog; } } 

}

Desactiva la aceleración de hardware en el archivo manifest.xml, y mi aplicación no muestra mapa negro de nuevo en segunda carga. Lo intento en el emulador.

 <application android:hardwareAccelerated="false"> ... </application 

De este artículo: http://developer.android.com/guide/topics/graphics/hardware-accel.html

Un poco tarde pero, descubrí que WebViews (incluso en otros fragmentos) alguna vez "bloquea" el motor GL o algo que resulta en pantallas negras en el MapView. He encontrado en LogCat esto:

 09-30 10:58:17.765: E/libEGL(29805): call to OpenGL ES API with no current context (logged once per thread) 09-30 10:58:17.765: W/Adreno200-EGL(29805): <qeglDrvAPI_eglSwapBuffers:3421>: EGL_BAD_CONTEXT 09-30 10:58:17.765: W/HardwareRenderer(29805): EGL error: EGL_BAD_CONTEXT 09-30 10:58:17.775: W/HardwareRenderer(29805): Mountain View, we've had a problem here. 

Cambiar de nuevo a la representación del software. Para corregir esto cuando el WebView se desprende llamo a la función de destruir, en un Fragmento así:

 @Override public void onDestroyView() { if (webView != null) { webView.destroy(); webView = null; } super.onDestroyView(); } 

Tal vez le dará una dirección en la solución de este problema también.

  • Edición de Android Dibujo de rutas largas en MapView mediante análisis XML
  • Obtener altitud por longitud y latitud en Android
  • ¿Por qué volver a recuperar Google Maps para Android usando datos KML ya no funciona?
  • Vista de Google Maps dentro de un RecyclerView
  • Android mapview con fragmentos no se puede agregar dos veces?
  • Android cómo obtener temprature de la ubicación en mapview
  • Android Mapview: Fusionar marcadores superpuestos en un nuevo marcador
  • ¿Cómo mostrar el popup en la superposición de tapping en android?
  • Android Rotación de MapView
  • Cómo configurar el control de zoom con setBuiltInZoomControls (true)?
  • Almacenamiento en caché de superposiciones al redondear rectángulos de coordenadas - ¿cómo?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.