2010-04-19 7 views
6

Manchmal bekomme ich 0 und 360 * 1E6, wenn ich versuche, den Breitengrad oder Längengrad einer MapView mit getLatitudeSpan() und getLongitudeSpan() zu erhalten. Das passiert nicht immer, aber es ist ein Problem, hat jemand dieses Problem? Irgendwelche Problemumgehungen? Ich habe versucht, getProjection() zu verwenden, aber ich bekomme das gleiche Problem. Hier ist das Stück Code:Mapview getLatitudeSpan und getLongitudeSpan funktionieren nicht

MapView mapView = (MapView) findViewById(R.id.mapview); 
int lat = mapView.getLatitudeSpan(); // sometimes returns 0 
int long = mapView.getLongitudeSpan(); // sometimes returns 360*1E6 
+0

Wann führen Sie diesen Code aus? Sie haben keine Breite oder Länge, bis Sie einen Mittelpunkt und eine Zoomstufe festlegen und die Karte auf dem Bildschirm gerendert wird. – CommonsWare

+0

Ich habe diesen Code in OnCreate und innerhalb einer AsyncTask, die ich verwende, um einige Daten zu downloaden. Ich stelle die Zoomstufe ein und zentriere auf onCreate.Ich habe bemerkt, dass dies die meiste Zeit passiert, wenn ich meine App zum ersten Mal benutze, nachdem ich es wieder benutzt habe und ich wieder zur Aktivität komme, komme ich normalerweise nicht auf dieses Problem. –

Antwort

3

Ich würde den Zustand erkennen und planen Sie Ihre Arbeit nach ein paar hundert Millisekunden erneut versuchen. AFAIK, diese Werte werden schließlich verfügbar werden, aber sie können eher Timing-abhängig sein. Theoretisch sollten sie berechnet werden, nachdem Sie die Mitte festgelegt und den Zoom festgelegt haben, aber ich vermute, dass sie erst berechnet werden, nachdem die gerendert wurde, und möglicherweise nicht, bis einige Kartendaten aus dem Internet heruntergeladen werden.

Isolieren Sie also Ihren Code, der von diesen Spannen abhängt, in eine Methode. Rufen Sie diese Methode von onCreate() und die AsyncTask, wahrscheinlich als Sie heute tun. Fügen Sie jedoch eine Erkennungslogik hinzu, um die ungültigen Werte zu finden, und rufen Sie dann postDelayed() auf Ihrer (oder einer anderen View) auf, um die Methode nach ein paar hundert Millisekunden erneut aufzurufen, wenn die Werte ungültig sind. Sie müssen möglicherweise auch eine Art von Zähler hinzufügen, so dass Sie diese postDelayed() Sachen auf unbestimmte Zeit nicht tun.

Dies ist natürlich ein Hack. Da die Google Maps-Komponente jedoch nicht Open Source ist, ist es schwierig, etwas Solides zu finden.

+0

ist dies wirklich die beste Lösung, um Bildschirmkoordinaten zu erhalten, wenn eine Kartenansicht zuerst geladen wird? scheint so ein Hack ... Gibt es wirklich keinen Rückruf? – edthethird

+0

@edthethird: Da Maps V1 jetzt veraltet ist, sollten Sie sich Maps V2 ansehen. – CommonsWare

+0

hmm Ich bin, aber ich habe immer noch das gleiche Problem-- versuchen, .getProjection() in OnResume() und es ist leer .. Suche nach Callback im Idealfall aber am Ende mit asynchronen Aufgabe warten endete – edthethird

0

getLatitudeSpan und getLongitudeSpan funktionieren nur, um Ihnen die Spannen für den sichtbaren Teil der Karte zu geben. Wenn Sie sie in onCreate() aufrufen, wird die Karte nicht immer angezeigt. Ruf sie stattdessen in onStart() an und es sollte dir gut gehen.

+1

Dies funktioniert auch nicht. 'getLongitudeSpan' gibt nach' onStart' noch '360 * 1E6' zurück – skaffman

2

Ich habe mit diesem Herumspielen ... und eine mapview in einem Tabbed-Aktivität ... die Werte werden nicht bis onResume initialisiert() ... Ich überprüfte dies, indem sie:

 final Handler mHandler = new Handler(); 
     mHandler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       latSpan = mapView.getLatitudeSpan(); 
       lngSpan = mapView.getLongitudeSpan(); 
       if ((latSpan == 0) && (lngSpan == 360000000)) { 
        count++; 
        System.out.println("here we go again! " + count); 
        mHandler.postDelayed(this, 100); 
       }  
      } 
     }, 100); 

An verschiedenen Stellen ... in onCreate() und onStart() wird es unbegrenzt gehen (bis ich zu dieser Registerkarte wechseln), in onResume() erhält es sofort korrekte Werte.

8

Ich habe genau dasselbe Problem durchlaufen und die oben genannten Lösungen funktioniert. Ich möchte jedoch eine klarere Implementierung für alle Anfänger vorstellen.

Definieren Sie eine Ansichtsvariable für Ihre Karte: private MapView mapView;

Und die mapview zuweisen:

mapView = (MapView) findViewById(R.id.mapview); 

Fügen Sie die folgende Methode:

/** 
    * Wait for mapview to become ready. 
    */ 
    private Runnable waitForMapTimeTask = new Runnable() { 
     public void run() { 
      // If either is true we must wait. 
      if(mapView.getLatitudeSpan() == 0 || mapView.getLongitudeSpan() == 360000000) 
       mapView.postDelayed(this, TIME_TO_WAIT_IN_MS); 
     } 
    }; 

In Ihrem onCreate/onResume fügen Sie folgendes vor dem Aufruf getLatitudeSpan:

mapView.postDelayed(waitForMapTimeTask, TIME_TO_WAIT_IN_MS); 

Und Sie sind gut zu gehen :)