Autore Topic: Aggiungere Marker sulla mappa con coordinate prese da un HttpClient  (Letto 1984 volte)

Offline Ivan86

  • Utente junior
  • **
  • Post: 139
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S II
  • Sistema operativo:
    Windows 7
Ciao,
pensavo di aver capito come funzionano le nuove mappe, quando mi ritrovo in un nuovo problema.

Sto cercando di caricare i Marker prelevando Lat e Lon direttamente da un DB presente su server.
Vi posto il mio codice e anche l'errore del Logcat.

Codice (Java): [Seleziona]
public class MappaV2Activity extends Activity implements OnMarkerClickListener,
                                                                                          OnInfoWindowClickListener,
                                                                                          OnMarkerDragListener,
                                                                                          OnMyLocationChangeListener{

private ArrayList<Marker> mMarkers;
JSONArray jArray;
JSONObject json_data;
...
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.mappa);
                 
                //Verifica la abilitazione della mappa
                setUpMapIfNeeded();
                ...
        }

        private void setUpMapIfNeeded() {
            // Do a null check to confirm that we have not already instantiated the map.
            if (mapV2 == null) {
                mapV2 = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
                // Check if we were successful in obtaining the map.
                if (mapV2 != null) {
                    // The Map is verified. It is now safe to manipulate the map.
                        setUpMap();
                }
            }
        }

private void setUpMap() {
                //Aggiungo Marker sulla mappa. creo e avvio asynctask
               GetMarkerTask mTask = new GetMarkerTask();
               mTask.execute();
           
                // Impostazioni della mappa
                mapV2.moveCamera(CameraUpdateFactory.newLatLngZoom(ITALY, 6));
                mapV2.getUiSettings().setCompassEnabled(false);
                mapV2.getUiSettings().setTiltGesturesEnabled(false);
                mapV2.getUiSettings().setRotateGesturesEnabled(true);
                mapV2.setMyLocationEnabled(true);
                mapV2.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                //Set della info window
//        mapV2.setInfoWindowAdapter(new CustomInfoWindowAdapter());
        // Set listeners for marker events.  See the bottom of this class for their behavior.
        mapV2.setOnMarkerClickListener(this);
        mapV2.setOnInfoWindowClickListener(this);
        mapV2.setOnMarkerDragListener(this);
                mapV2.setOnMyLocationChangeListener(this);

        // Pan to see all markers in view.
        // Cannot zoom to bounds until the map has a size.
        final View mapView = getFragmentManager().findFragmentById(R.id.map).getView();
        if (mapView.getViewTreeObserver().isAlive()) {
            mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                @SuppressWarnings("deprecation")        // We use the new method when supported
                @SuppressLint("NewApi")                         // We check which build version we are using.
                public void onGlobalLayout() {
                        LatLngBounds.Builder bld = new LatLngBounds.Builder();
                        try {
                                for(int i=0;i<jArray.length();i++){
                                        json_data = jArray.getJSONObject(i);
                                LatLng ll = new LatLng(json_data.getDouble("lat"),json_data.getDouble("lon"));
                                bld.include(ll);            
                            }
                                        } catch (JSONException e) {
                                                e.printStackTrace();
                                        }
                    LatLngBounds bounds = bld.build();
                    mapV2.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 70));
                   
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                        mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                      } else {
                        mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                      }
                }
            });
        }
        }

       private class GetMarkerTask extends AsyncTask<String,String,String>  {
            protected String doInBackground(String... params) {

                mapV2.clear();

                InputStream is  = null;
               
                try{
                        HttpClient httpclient = new DefaultHttpClient();
                        HttpPost httppost = new HttpPost("http://www.miosito.it/overlay.php");
                        HttpResponse response = httpclient.execute(httppost);
                        HttpEntity entity = response.getEntity();
                        is = entity.getContent();
                }catch(Exception e){
                        Log.e("log_REMOTO", "Errore nella connessione HTTP: "+e.toString());
                        Toast.makeText(MappaV2Activity.this, "Connessione non riuscita", Toast.LENGTH_SHORT).show();
                }
                try{  
                        BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                        StringBuilder sb = new StringBuilder();
                        String line = null;
                        while ((line = reader.readLine()) != null) {
                        sb.append(line + "\n");        
                        }
                        is.close();
                        result = sb.toString();
                       
                }catch(Exception e){
                Log.e("log_REMOTO", "Errore nella conversione del risultato: "+e.toString());
                }
                try{
                        jArray = new JSONArray(result);
                        for(int i=0;i<jArray.length();i++){
                                json_data = jArray.getJSONObject(i);
       
                    LatLng ll = new LatLng(json_data.getDouble("lat"),json_data.getDouble("lon"));
                    BitmapDescriptor bitmapMarker;
                   
                    if (json_data.getString("tipo").equals("neg")){
                        bitmapMarker = BitmapDescriptorFactory.fromResource(R.drawable.red1);
                    }
                    if (json_data.getString("tipo").equals("pos")){
                        bitmapMarker = BitmapDescriptorFactory.fromResource(R.drawable.green1);
                    }
                    mMarkers.add(mapV2.addMarker(new MarkerOptions()
                                .position(ll)
                                .title(json_data.getString("tipo"))
                                .snippet(json_data.getString("luogo"))
                                .icon(bitmapMarker)));
                      }        
               }catch(JSONException e1){
                        Log.e("log_REMOTO", "Errore json: "+e1.toString());
                }catch (Exception e1){
                        Log.e("log_REMOTO", "Errore JSON: "+e1.toString());
                        e1.printStackTrace();  
                }
                return result;  
        }
    }

Questo l'errore:
Codice: [Seleziona]
E/AndroidRuntime( 9681): FATAL EXCEPTION: AsyncTask #2
E/AndroidRuntime( 9681): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime( 9681):        at android.os.AsyncTask$3.done(AsyncTask.java:299)
E/AndroidRuntime( 9681):        at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
E/AndroidRuntime( 9681):        at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
E/AndroidRuntime( 9681):        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
E/AndroidRuntime( 9681):        at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/AndroidRuntime( 9681):        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
E/AndroidRuntime( 9681):        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
E/AndroidRuntime( 9681):        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
E/AndroidRuntime( 9681):        at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime( 9681): Caused by: java.lang.IllegalStateException: Not on the main thread
E/AndroidRuntime( 9681):        at maps.ap.q.b(Unknown Source)
E/AndroidRuntime( 9681):        at maps.au.e.b(Unknown Source)
E/AndroidRuntime( 9681):        at maps.z.ag.clear(Unknown Source)
E/AndroidRuntime( 9681):        at com.google.android.gms.maps.internal.IGoogleMapDelegate$Stub.onTransact(IGoogleMapDelegate.java:205)
E/AndroidRuntime( 9681):        at android.os.Binder.transact(Binder.java:326)
E/AndroidRuntime( 9681):        at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.clear(Unknown Source)
E/AndroidRuntime( 9681):        at com.google.android.gms.maps.GoogleMap.clear(Unknown Source)
E/AndroidRuntime( 9681):        at it.tesi.MappaV2Activity$GetMarkerTask.doInBackground(MappaV2Activity.java:[b]218[/b])
E/AndroidRuntime( 9681):        at it.tesi.MappaV2Activity$GetMarkerTask.doInBackground(MappaV2Activity.java:1)
E/AndroidRuntime( 9681):        at android.os.AsyncTask$2.call(AsyncTask.java:287)
E/AndroidRuntime( 9681):        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
la riga 218 corrisponde a: mapV2.clear();

se metto a commento quella riga di codice allora l'errore diventa questo:
Codice: [Seleziona]
E/AndroidRuntime(21608): FATAL EXCEPTION: main
E/AndroidRuntime(21608): java.lang.NullPointerException
E/AndroidRuntime(21608):        at it.tesi.MappaV2Activity$2.onGlobalLayout(MappaV2Activity.java:396)
E/AndroidRuntime(21608):        at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:678)
E/AndroidRuntime(21608):        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1855)
E/AndroidRuntime(21608):        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1115)
E/AndroidRuntime(21608):        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4526)
E/AndroidRuntime(21608):        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
E/AndroidRuntime(21608):        at android.view.Choreographer.doCallbacks(Choreographer.java:555)
E/AndroidRuntime(21608):        at android.view.Choreographer.doFrame(Choreographer.java:525)
E/AndroidRuntime(21608):        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
E/AndroidRuntime(21608):        at android.os.Handler.handleCallback(Handler.java:615)
E/AndroidRuntime(21608):        at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(21608):        at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(21608):        at android.app.ActivityThread.main(ActivityThread.java:4921)
E/AndroidRuntime(21608):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(21608):        at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(21608):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
E/AndroidRuntime(21608):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
E/AndroidRuntime(21608):        at dalvik.system.NativeStart.main(Native Method)
la riga 384 corrisponde a: for(int i=0;i<jArray.length();i++){
« Ultima modifica: 03 Aprile 2013, 10:19:02 CEST da Ivan86 »

Offline Nicola_D

  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Aggiungere Marker sulla mappa con coordinate prese da un HttpClient
« Risposta #1 il: 28 Marzo 2013, 22:35:45 CET »
0
non puoi dentro ad un async task fare chiamate che interagiscono direttamente con la UI, a meno che tu non faccia:
Codice (Java): [Seleziona]
runOnUiThread(new Runnable() {
                public void run() {
                    // some code #3 (that needs to be ran in UI thread)

                }
            });
ci sono anche discussioni a riguardo multithreading - Android: RunOnUiThread vs AsyncTask - Stack Overflow

Personalmente l'async task lo userei solo per ottenere i dati e ripulirli (se necessario).
La mappa la modificherei fuori dall'async task
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline Ivan86

  • Utente junior
  • **
  • Post: 139
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S II
  • Sistema operativo:
    Windows 7
Re:Aggiungere Marker sulla mappa con coordinate prese da un HttpClient
« Risposta #2 il: 28 Marzo 2013, 23:03:20 CET »
0
Ho provato a dividere httpClient e addMarker, ma ho riscontrato il secondo stesso errore da me postato nel primo post:
Codice: [Seleziona]
E/AndroidRuntime(21608): FATAL EXCEPTION: main
E/AndroidRuntime(21608): java.lang.NullPointerException
E/AndroidRuntime(21608):        at it.tesi.MappaV2Activity$2.onGlobalLayout(MappaV2Activity.java:396)
E/AndroidRuntime(21608):        at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:678)
E/AndroidRuntime(21608):        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1855)
E/AndroidRuntime(21608):        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1115)
E/AndroidRuntime(21608):        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4526)
E/AndroidRuntime(21608):        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
E/AndroidRuntime(21608):        at android.view.Choreographer.doCallbacks(Choreographer.java:555)
E/AndroidRuntime(21608):        at android.view.Choreographer.doFrame(Choreographer.java:525)
E/AndroidRuntime(21608):        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
E/AndroidRuntime(21608):        at android.os.Handler.handleCallback(Handler.java:615)
E/AndroidRuntime(21608):        at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(21608):        at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(21608):        at android.app.ActivityThread.main(ActivityThread.java:4921)
E/AndroidRuntime(21608):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(21608):        at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(21608):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
E/AndroidRuntime(21608):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
E/AndroidRuntime(21608):        at dalvik.system.NativeStart.main(Native Method)

In più ho provato a farmi stampare i dati del JSONarray ma non mi stampa niente.
Codice (Java): [Seleziona]
                        for(int i=0;i<jArray.length();i++){
                                json_data = jArray.getJSONObject(i);
                                Log.i("log_tag","LAT: "+json_data.getString("lat")+
                                        ", LON: "+json_data.getString("lon"));
                                ...

Offline Nicola_D

  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Aggiungere Marker sulla mappa con coordinate prese da un HttpClient
« Risposta #3 il: 29 Marzo 2013, 08:19:54 CET »
0
la riga corrisponde sempre al ciclo?
« Ultima modifica: 29 Marzo 2013, 08:21:34 CET da Nicola_D »
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline Ivan86

  • Utente junior
  • **
  • Post: 139
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S II
  • Sistema operativo:
    Windows 7
Re:Aggiungere Marker sulla mappa con coordinate prese da un HttpClient
« Risposta #4 il: 29 Marzo 2013, 09:39:08 CET »
0
Si.
Se noti ho due cicli for.
Uno per recuperare i dati dopo che uso il metodo httpClient.
L'altro for (dove mi da errore), presente  in setUpMap(), per caricare i marker sulla mappa.

La cosa strana è che ho messo un Log.i per stampare quello che preleva dall'httpClient, ma non stampa nulla, come se a quel log non ci arrivasse.

Non è che non entra mai nel if (mapV2 != null) ? e quindi quando arriva al secondo for, trova l'array vuoto?

Offline Nicola_D

  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Aggiungere Marker sulla mappa con coordinate prese da un HttpClient
« Risposta #5 il: 29 Marzo 2013, 11:04:39 CET »
0
a parte che il codice è un po difficile da leggere (quando lo incolli qui formattalo gentilmente),
ma ti manca una cosa essenziale, tu lanci l'async task e poi vai avanti per i fatti tuoi. Stando su un'altro thread è un'operazione parallela.
Tu devi ciclare su jArray solo DOPO che l'async task ha scaricato i dati. Questo non centra niente con le gmaps api, si tratta di download di dati in background.
Ci sono tanti tutorial da cui prendere spunto, sistema quella parte e vedrai che poi ti funziona tutto!
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline Ivan86

  • Utente junior
  • **
  • Post: 139
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S II
  • Sistema operativo:
    Windows 7
Re:Aggiungere Marker sulla mappa con coordinate prese da un HttpClient
« Risposta #6 il: 29 Marzo 2013, 11:45:48 CET »
0
E dire che pensavo di aver indentato bene il codice xD ok la prossima volta mi impegno :)

Tornando a noi. Come faccio a ciclare sul jArray quando ha finito di elaborare i dati dall AsyncTask?
Ho provato a stamparmi i risultati mettendo il ciclo sul jArray nel onPostExecute ma niente...
:(

Offline Nicola_D

  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Aggiungere Marker sulla mappa con coordinate prese da un HttpClient
« Risposta #7 il: 29 Marzo 2013, 14:07:38 CET »
0
fai le cose una per volta, segui un tutorial che usa gli async task e fai in modo che tu riesca a ricevere e salvare i dati.
Se scrivi "ho fatto ma niente..." è impossibile aiutarti!
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline Ivan86

  • Utente junior
  • **
  • Post: 139
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S II
  • Sistema operativo:
    Windows 7
Re:Aggiungere Marker sulla mappa con coordinate prese da un HttpClient
« Risposta #8 il: 30 Marzo 2013, 20:31:19 CET »
0
Sono un fagiano!
Stamattina ho trovato quale era il problema...
Semplicemente non mi ero accorto che il metodo onPostExecute lo avevo messo al di fuori della classe AsyncTask e quindi non ci entrava mai  :-P

Questo mi rincuora... sto tornando a capire la programmazione Android xD

Grazie per la pazienza