Autore Topic: Problema con localizzazione una tantum  (Letto 1791 volte)

Offline dodopepper

  • Utente junior
  • **
  • Post: 124
  • Respect: +4
    • Mostra profilo
  • Dispositivo Android:
    HTC Magic 32a black
Problema con localizzazione una tantum
« il: 02 Giugno 2010, 13:52:26 CEST »
0
Salve a tutti ragazzi, sono di nuovo qui a chiedere aiuto. Nella mia applicazione ho la necessità di trovare la posizione al momento in cui scatto la foto, praticamente la devo semplicemente geotaggare. Non ho problemi prendendo l'ultima posizione disponibile mentre non riesco a "forzare" un singolo aggiornamento. Vi posto prima il codice e poi lo commento
Codice (Java): [Seleziona]
@Override
                        public void onPictureTaken(final byte[] data, Camera camera) {
                                       
                                //Quando si scatta la foto prendiamo la posizione
                        locMan= (LocationManager) getSystemService(Context.LOCATION_SERVICE);
                        criteria=new Criteria();
                        //criteria.setAccuracy(Criteria.ACCURACY_FINE);
                         if(!locMan.isProviderEnabled("gps"))
                 Toast.makeText(TakePhoto.this, "GPS è attualmente disabilitato. E' possibile abilitarlo dal menu impostazioni.", Toast.LENGTH_LONG).show();
                        bestProv = locMan.getBestProvider(criteria, false);
                        Log.d("MOWISdroid.TakePhoto",bestProv);
                        if(bestProv.compareTo("gps")==1){}
                        Location luogo=new Location(bestProv);
                                //locMan.getLastKnownLocation(bestProv);
                        Log.d("MOWISdroid.TakePhoto",String.valueOf( luogo.getAccuracy()));
                        Log.d("MOWISdroid.TakePhoto",bestProv);
                        if(luogo.getAccuracy()>500){locMan.requestLocationUpdates(bestProv, 500, 500,TakePhoto.this);
                        Log.d("MOWISdroid.TakePhoto",bestProv);
                        Log.d("MOWISdroid.TakePhoto",String.valueOf( luogo.getAccuracy()));}
                        Lat= Float.valueOf((float)luogo.getLatitude());
                        Long= Float.valueOf((float)luogo.getLongitude());
                        float[] coordinate={Lat.floatValue(),Long.floatValue()};
                        //una volta scattata la foto chiamo l'activity di tagging passando nell'intent lo stream di byte
                        //rappresentante l'immagine
                        Intent launchTag= new Intent(TakePhoto.this,TagPhoto.class);
                        launchTag.putExtra(getPackageName()+".pict", data);
                        launchTag.putExtra(getPackageName()+".coord", coordinate);
                        startActivity(launchTag);
                                };

@Override
        public void onLocationChanged(Location location) {
                //bestProv = locMan.getBestProvider(criteria, false);
                luogo= location;
                locMan.removeUpdates(TakePhoto.this);
               
        }

        @Override
        public void onProviderDisabled(String provider) {
                // TODO Auto-generated method stub
               
        }

        @Override
        public void onProviderEnabled(String provider) {
                // TODO Auto-generated method stub
               
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
                bestProv = provider;
                locMan.removeUpdates(TakePhoto.this);
               
        }


Il primo problema è che imposto il criteria ad accuracy_fine l'applicazione va in crash, inoltre se il gps è attivo non si attiva, non rileva la posizione e l'applicazione va in crash, se invece localizzo con la rete (network) non ci sono problemi ma cmq fra la prima "rilevazione" e la seconda non ci sono cambiamenti nè in precisione nè in coordinate.

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Problema con localizzazione una tantum
« Risposta #1 il: 03 Giugno 2010, 11:43:19 CEST »
0
Nel manifest hai impostato correttamente il permesso android.permission.ACCESS_FINE_LOCATION?

Offline dodopepper

  • Utente junior
  • **
  • Post: 124
  • Respect: +4
    • Mostra profilo
  • Dispositivo Android:
    HTC Magic 32a black
Re:Problema con localizzazione una tantum
« Risposta #2 il: 03 Giugno 2010, 12:43:08 CEST »
0
Sisi l'avevo impostato, ho parzialmente risolto chiedendo l'aggiornamento all'interno dell'onCreate, il codice è il seguente:
Codice (Java): [Seleziona]
public class TakePhoto extends Activity implements SurfaceHolder.Callback, LocationListener  {


        /* VARIABILI PRIVATE */
        private SurfaceView surface;
        private SurfaceHolder surfHolder;
        public Camera fotocamera;
        //private Button otturatore;
        private PictureCallback jpeg ;
        //private File foto;
        private static final String path_file = "fotografia.jpeg";
        public ProgressDialog messaggioUp;
        private Float Lat, Long;
        LocationManager locMan;
        String bestProv;
        Location luogo;
        Criteria criteria;
        Boolean gpsFixed=false;
        GpsStatus.Listener gpsListener;


       
       
       
       
        @Override
    public void onCreate(Bundle savedInstanceState2)  {
       
                super.onCreate(savedInstanceState2);
        getWindow().setFormat(PixelFormat.TRANSLUCENT); //aggiungo il traslucido OK
        requestWindowFeature(Window.FEATURE_NO_TITLE);  //no barra titolo OK
       // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);   //full screen
        setContentView(R.layout.maincamera);
        surface= (SurfaceView) findViewById(R.id.SurfaceView01);
                locMan= (LocationManager) getSystemService(Context.LOCATION_SERVICE);
                criteria=new Criteria();
                criteria.setAccuracy(Criteria.ACCURACY_FINE);
                //criteria.setAccuracy(Criteria.ACCURACY_COARSE);
                bestProv = locMan.getBestProvider(criteria, false);
                locMan.requestLocationUpdates(bestProv, 0, 0,TakePhoto.this);
                if(!locMan.isProviderEnabled(LocationManager.GPS_PROVIDER))
            Toast.makeText(TakePhoto.this, "GPS è attualmente disabilitato. E' possibile abilitarlo dal menu impostazioni.", Toast.LENGTH_LONG).show();
               
                gpsListener = new GpsStatus.Listener() {
                       
                        @Override
                        public void onGpsStatusChanged(int event) {
                                Log.i("MOWISdroid", "Gps status changed");
                                if(event==GpsStatus.GPS_EVENT_FIRST_FIX){
                                        gpsFixed=true;
                                        Log.i("MOWISdroid", "Gps signal fixed");
                                }
                                                               
                        }
                };
                locMan.addGpsStatusListener(gpsListener);
               
                surface.setOnClickListener(new OnClickListener(){

                        @Override
                        public void onClick(View arg0) {
                                //Implementa l'azione eseguita dall'otturatore
                                //Incapsuliamo la funzione di autofocus in modo che prima di scattare metta a fuoco l'immagine
                               
                                fotocamera.autoFocus(new AutoFocusCallback(){

                                        @Override
                                        public void onAutoFocus(boolean success, Camera camera) {
                                                fotocamera.takePicture(null, null, jpeg);
                                               
                                        }
                                       
                                });
                               
                               
                                                                                        }
               
                                                                                                        });
       
        jpeg= new Camera.PictureCallback() {
                       
                        @Override
                        public void onPictureTaken(final byte[] data, Camera camera) {
                                       
                                //Quando si scatta la foto prendiamo la posizione
                       
                        if (!gpsFixed)bestProv=LocationManager.NETWORK_PROVIDER;
                        luogo=locMan.getLastKnownLocation(bestProv);
                        Log.d("MOWISdroid","Provider: " + bestProv);
                        Log.i("MOWISdroid","Geolocation accuracy: " +String.valueOf( luogo.getAccuracy()));
                        locMan.removeUpdates(TakePhoto.this);
                        locMan.removeGpsStatusListener(gpsListener);
                        Lat= Float.valueOf((float)luogo.getLatitude());
                        Long= Float.valueOf((float)luogo.getLongitude());
                        float[] coordinate={Lat.floatValue(),Long.floatValue()};
                        //una volta scattata la foto chiamo l'activity di tagging passando nell'intent lo stream di byte
                        //rappresentante l'immagine
                        Intent launchTag= new Intent(TakePhoto.this,TagPhoto.class);
                        launchTag.putExtra(getPackageName()+".pict", data);
                        launchTag.putExtra(getPackageName()+".coord", coordinate);
                        startActivity(launchTag);
                                };
                                       
                                       
                                               
                };
       
        surfHolder = surface.getHolder();
        surfHolder.addCallback(this);
        surfHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);        //tipo di surface, suggerito nei tutorial ufficiali

             
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                        int height) {
                 //setto le preferenze
        Camera.Parameters p = fotocamera.getParameters();  //prendo le preferenze della camera
        p.setWhiteBalance("auto");
        //p.setPreviewSize(width, height);
        ArrayList<Size> list = (ArrayList<Size>) p.getSupportedPictureSizes();  //recuepro le risoluzioni supportate dalla camera
        int picture_width = list.get(list.size()-1).width;
        int picture_height = list.get(list.size()-1).height;
        p.setPictureSize(picture_width, picture_height);        //setto la camera alla risoluzione più bassa
        p.setJpegQuality(80);   // qualità compressione JPEG

        // salvo le pref
        fotocamera.setParameters(p);
               
                try {
                       
                        fotocamera.setPreviewDisplay(holder);
                        fotocamera.startPreview();
                } catch (IOException e) {
                                               
                                        }
               
               
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
                fotocamera=Camera.open();
               
               
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
                fotocamera.stopPreview();
                fotocamera.release();
               
        }

        @Override
        public void onLocationChanged(Location location) {
                luogo= location;
                Log.i("MOWISdroid","Refreshing location" );
                Log.i("MOWISdroid","Now accuracy is: "+ String.valueOf(location.getAccuracy()) );
        }

        @Override
        public void onProviderDisabled(String provider) {
                bestProv = locMan.getBestProvider(criteria, false);
                locMan.requestLocationUpdates(bestProv, 0, 0,TakePhoto.this);
        }

        @Override
        public void onProviderEnabled(String provider) {
               
                bestProv = locMan.getBestProvider(criteria, false);
                locMan.requestLocationUpdates(bestProv, 0, 0,TakePhoto.this);
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
               
               
        }
       
       
       
       
       
       
}

Attualmente è il problema è che leggendo il log non sembra entrare nel metodo location changed...sopratutto quando il gps è disabilitato.... qualche consiglio?

Offline dodopepper

  • Utente junior
  • **
  • Post: 124
  • Respect: +4
    • Mostra profilo
  • Dispositivo Android:
    HTC Magic 32a black
Re:Problema con localizzazione una tantum
« Risposta #3 il: 03 Giugno 2010, 20:02:22 CEST »
0
Ragazzi idee? Sapete dirmi perchè non entra nell'onLocationChanged? Ovvero prima c'entrava ora non c'entra più, non trovo la relativa voce nel log....

Offline dodopepper

  • Utente junior
  • **
  • Post: 124
  • Respect: +4
    • Mostra profilo
  • Dispositivo Android:
    HTC Magic 32a black
Re:Problema con localizzazione una tantum
« Risposta #4 il: 06 Giugno 2010, 20:34:13 CEST »
0
Ragazzi up, non entra nell'onLocationChanged....è stranissimo!

Offline noodles

  • Utente junior
  • **
  • Post: 130
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus One
  • Sistema operativo:
    Mac OS X Snow Leopard
Re:Problema con localizzazione una tantum
« Risposta #5 il: 07 Giugno 2010, 21:58:52 CEST »
0
Ciao! Io ho avuto modo ieri mattina di vedere un po' l'utilizzo del GPS. Vedo con quel poco che ho capito se posso aiutarti.

Cmq... ho visto che usi Criteria, secondo me non ti conviene utilizzare questa classe a meno che tu non abbia particolari esigenze, nel tuo caso si tratta solo di geotaggare la foto perchè non usi semplicemente le celle GSM se non hai il GPS attivato?

Non ho mai usato direttamente Criteria, però c'è qualcosa che non mi convince nel tuo codice. Tu prima chiedi il bestProvider con ACCURACY_FINE con il flag a false, quindi a regola ti potrebbe restituire anche uno not enable ( che suppongo significhi che possa anche non essere disponibile) già qui metterei "true"; poi dopo registri la callback al provider per richiedere gli aggiornamenti e dopo verifichi se il GPS è attivo. Che senso ha? se il GPS non è attivo ti ritrovi con il bestProvider che potrebbe anche essere non disponibile, sempre se ho interpretato bene la documentazione  e qui potrebbe essere la magagna :)

Personalmente io prima verificherei che il GPS sia attivo, se è attivo allora lo preferisco come provider e lo registro, altrimenti prendi il bestProvider ma tra quelli abilitati (flag "true") anche se io a quel punto andrei di celle GSM con LocationManager.NETWORK_PROVIDER, che per geotaggare una foto vanno più che bene.  ;-)

Fammi sapere se ci sono news!

Offline dodopepper

  • Utente junior
  • **
  • Post: 124
  • Respect: +4
    • Mostra profilo
  • Dispositivo Android:
    HTC Magic 32a black
Re:Problema con localizzazione una tantum
« Risposta #6 il: 07 Giugno 2010, 22:19:51 CEST »
0
Si in effetti l'ho modificato parecchio dall'ultima volta che ho postato, considera che il mio apprendimento è "in fieri" quindi vado anche a tentativo. Infatti ultimamente avevo messo che se il gps non è attivo non registra il listener per il gps e automaticamente usa la rete gsm, fatto sta che cmq non ci entra nell'onLocationChanged. In effetti a sto punto i criteria li posso proprio eliminare anche se da quanto ho capito non fanno altro che vedere se il gps è attivo quindi faccio solo controlli su controlli. Purtroppo mi viene difficile anche far prove perchè dovrei mettermi a girare per la città quando con la network la precisione è sui 3km. Il gps lo devo usare perchè l'applicazione, se possibile, vorrebbe una localizzazione con precisione massima visto che è praticamente un'applicazione per i beni culturali (anche se nasce in un progetto più generico, poi  è stato specializzato). Insomma la vedo strana sta funzionalità di geotag. Dopo ti posto il codice come da aggiornamento.

Offline dodopepper

  • Utente junior
  • **
  • Post: 124
  • Respect: +4
    • Mostra profilo
  • Dispositivo Android:
    HTC Magic 32a black
Re:Problema con localizzazione una tantum
« Risposta #7 il: 07 Giugno 2010, 22:24:29 CEST »
0
Codice (Java): [Seleziona]
package it.unina.labadam.GUI;

import java.io.IOException;
import java.util.ArrayList;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.location.Criteria;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class TakePhoto extends Activity implements SurfaceHolder.Callback {


        /* VARIABILI PRIVATE */
        private SurfaceView surface;
        private SurfaceHolder surfHolder;
        public Camera fotocamera;
        private PictureCallback jpeg ;
        public ProgressDialog messaggioUp;
        private Float Lat, Long;
        LocationManager locMan;
        String bestProv;
        Location luogo;
        Criteria criteria;
        Boolean gpsFixed=false;
        GpsStatus.Listener gpsListener;
        LocationListener locList;

       
       
       
       
        @Override
    public void onCreate(Bundle savedInstanceState2)  {
       
                super.onCreate(savedInstanceState2);
        getWindow().setFormat(PixelFormat.TRANSLUCENT); //aggiungo il traslucido OK
        requestWindowFeature(Window.FEATURE_NO_TITLE);  //no barra titolo OK
       // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);   //full screen
        setContentView(R.layout.maincamera);
        surface= (SurfaceView) findViewById(R.id.SurfaceView01);
                locMan= (LocationManager) getSystemService(Context.LOCATION_SERVICE);
                criteria=new Criteria();
                criteria.setAccuracy(Criteria.ACCURACY_FINE);
                //criteria.setAccuracy(Criteria.ACCURACY_COARSE);
                bestProv = locMan.getBestProvider(criteria, false);
                locList=new LocationListener() {
                        @Override
                        public void onStatusChanged(String provider, int status, Bundle extras) {
                                // TODO Auto-generated method stub
                               
                        }
                       
                        @Override
                        public void onProviderEnabled(String provider) {
                                bestProv = locMan.getBestProvider(criteria, false);
                               
                        }
                       
                        @Override
                        public void onProviderDisabled(String provider) {
                                bestProv = locMan.getBestProvider(criteria, false);
                        }
                       
                        @Override
                        public void onLocationChanged(Location location) {
                                luogo= location;
                                Log.i("MOWISdroid","Refreshing location" );
                                Log.i("MOWISdroid","Now accuracy is: "+ String.valueOf(location.getAccuracy()) );
                               
                        }};

                try {locMan.requestLocationUpdates(bestProv, 0, 0,locList);            
                }catch(Exception e){Log.e("MOWISdroid", e.getMessage());}


                if(!locMan.isProviderEnabled(LocationManager.GPS_PROVIDER))
            Toast.makeText(TakePhoto.this, "GPS è attualmente disabilitato. E' possibile abilitarlo dal menu impostazioni.", Toast.LENGTH_LONG).show();
                else{
                gpsListener= new GpsStatus.Listener() {
                       
                        @Override
                        public void onGpsStatusChanged(int event) {
                                Log.i("MOWISdroid", "Gps status changed");
                                if(event==GpsStatus.GPS_EVENT_FIRST_FIX){
                                        gpsFixed=true;
                                        Log.i("MOWISdroid", "Gps signal fixed");
                                }
                                                               
                        }};
                locMan.addGpsStatusListener(gpsListener);}
               
                surface.setOnClickListener(new OnClickListener(){

                        @Override
                        public void onClick(View arg0) {
                                //Implementa l'azione eseguita dall'otturatore
                                //Incapsuliamo la funzione di autofocus in modo che prima di scattare metta a fuoco l'immagine
                               
                                fotocamera.autoFocus(new AutoFocusCallback(){

                                        @Override
                                        public void onAutoFocus(boolean success, Camera camera) {
                                                fotocamera.takePicture(null, null, jpeg);
                                               
                                        }
                                       
                                });
                               
                               
                                                                                        }
               
                                                                                                        });
       
        jpeg= new Camera.PictureCallback() {
                       
                        @Override
                        public void onPictureTaken(final byte[] data, Camera camera) {
                                       
                                //Quando si scatta la foto prendiamo la posizione
                       
                        if (!gpsFixed)bestProv=LocationManager.NETWORK_PROVIDER;
                        luogo=locMan.getLastKnownLocation(bestProv);
                        Log.d("MOWISdroid","Provider: " + bestProv);
                        Log.i("MOWISdroid","Geolocation accuracy: " +String.valueOf( luogo.getAccuracy()));
                        locMan.removeUpdates(locList);
                        locMan.removeGpsStatusListener(gpsListener);
                        Lat= Float.valueOf((float)luogo.getLatitude());
                        Long= Float.valueOf((float)luogo.getLongitude());
                        float[] coordinate={Lat.floatValue(),Long.floatValue()};
                        //una volta scattata la foto chiamo l'activity di tagging passando nell'intent lo stream di byte
                        //rappresentante l'immagine
                        Intent launchTag= new Intent(TakePhoto.this,TagPhoto.class);
                        launchTag.putExtra(getPackageName()+".pict", data);
                        launchTag.putExtra(getPackageName()+".coord", coordinate);
                        startActivity(launchTag);
                                };
                                       
                                       
                                               
                };
       
        surfHolder = surface.getHolder();
        surfHolder.addCallback(this);
        surfHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);        //tipo di surface, suggerito nei tutorial ufficiali

             
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                        int height) {
                 //setto le preferenze
        Camera.Parameters p = fotocamera.getParameters();  //prendo le preferenze della camera
        p.setWhiteBalance("auto");
        //p.setPreviewSize(width, height);
        ArrayList<Size> list = (ArrayList<Size>) p.getSupportedPictureSizes();  //recuepro le risoluzioni supportate dalla camera
        int picture_width = list.get(list.size()-1).width;
        int picture_height = list.get(list.size()-1).height;
        p.setPictureSize(picture_width, picture_height);        //setto la camera alla risoluzione più bassa
        p.setJpegQuality(80);   // qualità compressione JPEG

        // salvo le pref
        fotocamera.setParameters(p);
               
                try {
                       
                        fotocamera.setPreviewDisplay(holder);
                        fotocamera.startPreview();
                } catch (IOException e) {
                                               
                                        }
               
               
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
                fotocamera=Camera.open();
               
               
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
                fotocamera.stopPreview();
                fotocamera.release();
               
        }

       
       
       
       
       
}

Ecco il codice (da notare che ho attinto a piene mani al tuo tutorial per la camera!). Quindi a questo punto toglierei anche i  criteria, fammi sapere che ne pensi.

Offline noodles

  • Utente junior
  • **
  • Post: 130
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus One
  • Sistema operativo:
    Mac OS X Snow Leopard
Re:Problema con localizzazione una tantum
« Risposta #8 il: 07 Giugno 2010, 22:45:00 CEST »
0
Secondo me ti conviene mettere il GSP come provider di default e se non è attivo passi alla rete GSM.
Poi con le callbacks del LocationListener: se da GSM attivi il GPS, lo setti come provider e lo registri, viceversa se lo disattivi.

I Criteria li leverei proprio. Ultima cosa... rimuovi anche gli updates per esempio quando l'activity va in stop e settali quando sei in onStart(), dovrebbe aiutarti a risparmiare batteria.  ;-)

Una domanda... perchè dici che l'errore e di circa 3Km? Non è tanto? Te lo chiedo per ignoranza mia... io pensavo che venisse fatta una triangolazione su 3 punti per determinare la posizione, sicuramente c'è un errore non trascurabile, ma dubito sia sull'ordine dei km.

Offline dodopepper

  • Utente junior
  • **
  • Post: 124
  • Respect: +4
    • Mostra profilo
  • Dispositivo Android:
    HTC Magic 32a black
Re: Problema con localizzazione una tantum
« Risposta #9 il: 07 Giugno 2010, 23:06:23 CEST »
0
Si avevo già pensato di fare l'override dell'onStart per risparmiare batteria, eh spesso la precisione va sull'ordine del km quando localizzo con il gsm, anche usando maps mi capita, comunque lo debbo perfezionare tutto il codice di questo programma...è solo un mesetto che programmo in android...

Sent from my Htcclay's SuperBad 3G using Tapatalk