web-dev-qa-db-fra.com

NoSuchFieldError: Aucun champ statique MapAttrs de type lors de l'utilisation de MapFragment avec Play Services 6.5

Il me manque peut-être quelque chose ici, mais je ne peux pas utiliser la nouvelle dépendance Maps uniquement dans Play Services 6.5

J'obtiens l'exception suivante:

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)

Manifeste:

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

Fichier Gradle:

compile 'com.google.Android.gms:play-services-maps:6.5.+'
compile 'com.Android.support:support-v4:21.0.2'

Disposition:

<fragment
   Android:id="@+id/map"
   Android:name="com.google.Android.gms.maps.MapFragment"
   Android:layout_width="match_parent"
   Android:layout_height="match_parent"/>

Est-ce cassé ou est-ce que je fais quelque chose de mal?

Le bundle complet me pousse au-dessus de la limite de dex et je préférerais ne pas utiliser le multidex

34
Philipp E.

Mise à jour de votre référentiel Google vers la version 15 via le SDK Manager devrait résoudre les problèmes et éliminer les besoins de solutions de contournement. Un projet propre est requis.

Android SDK

Ceci est également mentionné dans problème 7432 .

17
PaulR

Solution provisoire

remplacer le fragment de carte xml par un conteneur 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"/>-->

Créez le fragment dans le code et remplacez le conteneur

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

Veuillez noter que ce qui précède a été effectué dans "onCreate" dans une activité sans aucun autre fragment, alors assurez-vous d'adapter la transaction à votre cycle de vie et à votre logique.

5
ibit

J'ai trouvé un correctif "hacky" pour le faire fonctionner avec votre application jusqu'à ce que Google décide de résoudre ce problème:

Ajoutez ceci à votre script de gradation 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')
            }
        }
    }
}
4
pablisco

Je pense que vous avez une disposition dans la bibliothèque et le module avec le même nom ou gonfler plusieurs dispositions xml avec un identifiant de ressource en double.

Trouvez map_attrs dans play-services-lib et remplacez-le par ce code:

<?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>
1
Adnan

Enfin, j'ai découvert la cause. Si vous avez l'habitude d'enlever les fichiers aar pour votre propre bénéfice Eclipse (je ne vais pas enseigner ici comment parce que ce n'est pas le Android façon Studio), vous devez déplacer le fichier maps_attrs.xml sur le dossier play-services-base res/values ​​. Cela alignera les attributs et le fichier R.class généré sur le chemin de classe attendu par la bibliothèque de cartes.

Sample use of play-services-base

0
Pier Betos