android - google - NoSuchFieldError: ningún campo estático MapAttrs de tipo cuando se utiliza MapFragment con Play Services 6.5
google maps android example (5)
Tal vez me falta algo aquí, pero no puedo usar la nueva dependencia de Maps solamente en Play Services 6.5
Obtengo la siguiente excepción:
java.lang.NoSuchFieldError: No static field MapAttrs of type
[I in class Lcom/google/android/gms/R$styleable; or its superclasses
(declaration of ''com.google.android.gms.R$styleable'' appears in
/data/app/com.kaching.merchant.dev1-1/base.apk)
at com.google.android.gms.maps.GoogleMapOptions
.createFromAttributes(Unknown Source)
at com.google.android.gms.maps.SupportMapFragment
.onInflate(Unknown Source)
Manifiesto:
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="my-awesome-key"/>
<uses-permission
android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
Archivo Gradle:
compile ''com.google.android.gms:play-services-maps:6.5.+''
compile ''com.android.support:support-v4:21.0.2''
Diseño:
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
¿Está roto o estoy haciendo algo mal?
El paquete completo me lleva al límite de dex y prefiero no usar multidex
Creo que tiene el diseño tanto en la biblioteca como en el módulo con el mismo nombre o que infla el diseño de múltiples xml con una identificación de recursos duplicada.
Encuentra map_attrs en play-services-lib y reemplázalo con este código:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MapAttrs">
<attr name="mapType" format="enum">
<enum name="none" value="0"/>
<enum name="normal" value="1"/>
<enum name="satellite" value="2"/>
<enum name="terrain" value="3"/>
<enum name="hybrid" value="4"/>
</attr>
<attr name="cameraBearing" format="float"/>
<attr name="cameraTargetLat" format="float"/>
<attr name="cameraTargetLng" format="float"/>
<attr name="cameraTilt" format="float"/>
<attr name="cameraZoom" format="float"/>
<attr name="liteMode" format="boolean"/>
<attr name="uiCompass" format="boolean"/>
<attr name="uiRotateGestures" format="boolean"/>
<attr name="uiScrollGestures" format="boolean"/>
<attr name="uiTiltGestures" format="boolean"/>
<attr name="uiZoomControls" format="boolean"/>
<attr name="uiZoomGestures" format="boolean"/>
<attr name="useViewLifecycle" format="boolean"/>
<attr name="zOrderOnTop" format="boolean"/>
<attr name="uiMapToolbar" format="boolean"/>
<attr name="ambientEnabled" format="boolean"/>
</declare-styleable>
</resources>
Encontré una solución "hacky" para que funcione con tu aplicación hasta que Google decida solucionarlo:
Agregue esto a su secuencia de comandos gradle de la app
:
afterEvaluate {
def pattern = ~/process(.*)Resources/
tasks.matching { pattern.matcher(it.name).find() }.each {
def matcher = pattern.matcher(it.name)
matcher.find()
def buildType = matcher.group(1)
buildType = buildType.substring(0, 1).toLowerCase() + buildType.substring(1)
def rDirectory = "$project.buildDir/generated/source/r/$buildType"
it << {
def badFile = file("$rDirectory/com/google/android/gms/R.java")
def goodFile = file("$rDirectory/com/google/android/gms/maps/R.java")
if (badFile.exists() && goodFile.exists()) {
badFile.text = goodFile.text.replaceAll(''com.google.android.gms.maps'', ''com.google.android.gms'')
}
}
}
}
Finalmente descubrí la causa. Si tienes el hábito de secuestrar los archivos aar para tu propio beneficio de Eclipse (no voy a enseñar aquí cómo porque no es el modo de Android Studio), necesitas mover el archivo maps_attrs.xml en la base de servicios de juego. carpeta res / values . Esto alineará los atributos y el archivo R.class generado en la ruta de clase que la biblioteca de mapas está esperando.
La actualización de su repositorio de Google a la versión 15
través del SDK Manager debería resolver los problemas y eliminar las necesidades de las soluciones provisionales. Se requiere un proyecto limpio.
Esto también se menciona en el número 7432 .
Solución interina
reemplace el fragmento de mapa xml con un contenedor FrameLayout
<FrameLayout
android:id="@+id/map_container"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="0dp"
/>
<!--<fragment android:id="@+id/map"-->
<!--android:layout_weight="2"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="0dp"-->
<!--android:name="com.google.android.gms.maps.SupportMapFragment"/>-->
Crea el fragmento en el código y reemplaza el contenedor
SupportMapFragment supportMapFragment = SupportMapFragment.newInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.map_container,supportMapFragment).commit();
//this you should do anyway
supportMapFragment.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
//setup map - optional
UiSettings settings = googleMap.getUiSettings();
settings.setCompassEnabled(false);
settings.setZoomControlsEnabled(false);
settings.setAllGesturesEnabled(true);
settings.setMyLocationButtonEnabled(true);
}
});
Tenga en cuenta que lo anterior se hizo en ''onCreate'' en una actividad sin ningún otro fragmento, así que asegúrese de adaptar la transacción a su ciclo de vida y lógica.