Domanda

Sto scrivendo un app che richiede posizione corrente dell'utente (lastknownlocation non sarà molto utile) e visualizza un elenco di tutte le "voci" più vicini alla loro presi dal database.

ho avuto il ritrovamento degli oggetti più vicini a lavorare bene, ma solo con una latitudine hardcoded e longitudinale per il momento, ma ora è il momento di implementare trovare la posizione attuale.

Qualcuno può fornire un esempio di come avere l'applicazione trovare la bella posizione corrente in background e avere l'applicazione di attesa. Ho solo bisogno di una volta la posizione non aggiorna come la persona si muove. Ho implementato una posizione ascoltatore però Capisco sempre un fix GPS può essere lento. Ho visto altri esempi che utilizzano ultima posizione nota modalità di attuazione o l'ascoltatore posizione che continua a funzionare ed aggiornare tuttavia come la mia attività ha bisogno delle coordinate di posizione prima di poter visualizzare qualsiasi cosa l'applicazione appena si blocca. Ho bisogno di mostrare una finestra di avanzamento mentre la sua ricerca.

Come posso avere la corsa LocationListener volta in background e quindi rimuovere gli aggiornamenti di posizione una volta che trova la posizione. Ho bisogno del resto dell'applicazione di aspettare fino a quando non ha una posizione GPS o timeout dopo 20-30seconds dire. Vorrei un ProgressDialog in modo che l'utente sa che qualcosa sta succedendo, ma deve solo essere il non di animazione filatura carico una percentuale o nulla. Se possibile vorrei che l'utente sia in grado di annullare la finestra di dialogo se sono malati di attesa che poi si possono cercare digitando sobborgo ecc, invece.

Ho cercato di farlo con le discussioni ma sta diventando molto più complicato di quanto ritengo che dovrebbe essere e ancora non funziona comunque. Su iPhone questo è molto più semplice?

Qualcuno può fornire un bel modo di fare questo, ho strappando i capelli fuori per una settimana su questo ed è davvero mi mettendo in ritardo per il resto della data di completamento app.

In sintesi Voglio:
* Trova coordinate attuali
* Mostra finestra di avanzamento, mentre il recupero della posizione
* Avere app in grado di aspettare per la posizione di successo o di rinunciare dopo una certa ora?
* In caso di successo:. Respingere finestra di avanzamento e sull'uso di coordinate per eseguire i miei altri metodi per trovare oggetti nelle vicinanze
* Se Impossibile ottenere posizione: Respingere finestra di avanzamento e il messaggio di errore spettacolo, e incoraggiare utente al menu usare per andare alla ricerca di attività
. * Utilizzare queste coordinate, se le sceglie Mappa Utenti vista dal menu, per mostrare posizione corrente sulla mappa e perni di cadere in tutte le voci vicine utilizzando le loro coordinate dal database.

Grazie ragazzi, spero di aver spiegato abbastanza bene me stesso. Tutte le domande chiedono appena, sarò controllando con regolarità, perché io sono ansioso di ottenere questa parte completata. Acclamazioni

Modifica
Codice come richiesto

file di attività locationList

protected void onStart()
{
    super.onStart();

    // ....

    new LocationControl().execute(this);
}


private class LocationControl extends AsyncTask<Context, Void, Void>
{
    private final ProgressDialog dialog = new ProgressDialog(branchAtmList.this);

    protected void onPreExecute()
    {
        this.dialog.setMessage("Determining your location...");
        this.dialog.show();
    }

    protected Void doInBackground(Context... params)
    {
        LocationHelper location = new LocationHelper();

        location.getLocation(params[0], locationResult);

        return null;
    }

    protected void onPostExecute(final Void unused)
    {
        if(this.dialog.isShowing())
        {
            this.dialog.dismiss();
        }

        useLocation(); //does the stuff that requires current location
    }

}

public LocationResult locationResult = new LocationResult()
{
    @Override
    public void gotLocation(final Location location)
    {
        currentLocation = location;
    }
};  

class LocationHelper

    package org.xxx.xxx.utils;

import java.util.Timer;
/*
imports
*/

public class LocationHelper
{
    LocationManager locationManager;
    private LocationResult locationResult;
    boolean gpsEnabled = false;
    boolean networkEnabled = false;

    public boolean getLocation(Context context, LocationResult result)
    {       
        locationResult = result;

        if(locationManager == null)
        {
            locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        }
            //exceptions thrown if provider not enabled
            try
            {
                gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            }
            catch (Exception ex) {}
            try
            {
                networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            }
            catch (Exception ex) {}

            //dont start listeners if no provider is enabled
            if(!gpsEnabled && !networkEnabled)
            {
                return false;
            }

            if(gpsEnabled)
            {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
            }
            if(networkEnabled)
            {
                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
            }


            GetLastLocation();
            return true;
    }

    LocationListener locationListenerGps = new LocationListener() {
        public void onLocationChanged(Location location)
        {
            locationResult.gotLocation(location);
            locationManager.removeUpdates(this);
            locationManager.removeUpdates(locationListenerNetwork);

        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extra) {}
    };

    LocationListener locationListenerNetwork = new LocationListener() {
        public void onLocationChanged(Location location)
        {
            locationResult.gotLocation(location);
            locationManager.removeUpdates(this);
            locationManager.removeUpdates(locationListenerGps);

        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extra) {}

    };

    private void GetLastLocation()
    {
            locationManager.removeUpdates(locationListenerGps);
            locationManager.removeUpdates(locationListenerNetwork);

            Location gpsLocation = null;
            Location networkLocation = null;

            if(gpsEnabled)
            {
                gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            }
            if(networkEnabled)
            {
                networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            }

            //if there are both values use the latest one
            if(gpsLocation != null && networkLocation != null)
            {
                if(gpsLocation.getTime() > networkLocation.getTime())
                {
                    locationResult.gotLocation(gpsLocation);
                }
                else
                {
                    locationResult.gotLocation(networkLocation);
                }

                return;
            }

            if(gpsLocation != null)
            {
                locationResult.gotLocation(gpsLocation);
                return;
            }

            if(networkLocation != null)
            {
                locationResult.gotLocation(networkLocation);
                return;
            }

            locationResult.gotLocation(null);
    }

    public static abstract class LocationResult
    {
        public abstract void gotLocation(Location location);
    }
}

Questa sembra davvero come un grande sforzo solo per ottenere la posizione corrente una volta? Non ho bisogno di aggiornamenti o niente? Non c'è un modo più semplice di avere l'applicazione di attesa per un risultato? Sono stato bloccato su questo per così tanto tempo.

È stato utile?

Soluzione

Usare un AsyncTask e uso sia network_provider nonché gps_provider , che significa due ascoltatori. GPS richiede più tempo per ottenere una correzione, forse a volte un minuto e funziona solo all'aperto, mentre la rete ottiene una posizione piuttosto veloce.

Un buon esempio di codice è qui: Qual è il modo più semplice e robusto per ottenere la posizione corrente dell'utente su Android?

Per AsyncTask, guardare http://developer.android.com/reference /android/os/AsyncTask.html

Ci sono anche molti esempio di codice qui su SO per esso, per esempio qui: Android Visualizza una finestra di dialogo fino a quando un filo è fatto e poi continuare con il programma di

EDIT: Codice concetto:

variabile di classe add

boolean hasLocation = false;

chiamata a onCreate (non in AsyncTask):

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

poi nel locationListener.onLocationChanged, modificare il valore una volta che una posizione si trova:

boolean hasLocation = false;

AsyncTask: lasciare così com'è, ma non chiamare

LocationHelper location = new LocationHelper();
location.getLocation(params[0], locationResult);

lì, invece che fare

Long t = Calendar.getInstance().getTimeInMillies(); 
while (!hasLocation && Calendar.getInstance().getTimeInMillies()-t<30000)) {
    Thread.Sleep(1000); 
};    

Probabilmente con un ritardo tra sarebbe sufficiente.

Altri suggerimenti

Ancora non mi piace come funziona questo a tutti e sembra molto più complicato di quanto dovrebbe essere, ma fino a quando qualcuno offre un modo migliore ce l'ho a lavorare per la società ...

Se qualcuno viene in questo e suggerire una migliore risultato molto più pulito per ottenere solo correnti dell'utente coordinate di posizione solo una volta poi smettere di guardare che sarebbe molto apprezzato !!

private LocationControl locationControlTask;
private boolean hasLocation = false;
LocationHelper locHelper;

Da onCreate () I chiamare

locHelper = new LocationHelper();
locHelper.getLocation(context, locationResult);
locationControlTask = new LocationControl();
locationControlTask.execute(this);

Ho poi hanno un una classe privata LocationControl

private class LocationControl extends AsyncTask<Context, Void, Void>
    {
        private final ProgressDialog dialog = new ProgressDialog(activityname.this);

        protected void onPreExecute()
        {
            this.dialog.setMessage("Searching");
            this.dialog.show();
        }

        protected Void doInBackground(Context... params)
        {
            //Wait 10 seconds to see if we can get a location from either network or GPS, otherwise stop
            Long t = Calendar.getInstance().getTimeInMillis();
            while (!hasLocation && Calendar.getInstance().getTimeInMillis() - t < 15000) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            };
            return null;
        }

        protected void onPostExecute(final Void unused)
        {
            if(this.dialog.isShowing())
            {
                this.dialog.dismiss();
            }

            if (currentLocation != null)
            {
                useLocation();
            }
            else
            {
                //Couldn't find location, do something like show an alert dialog
            }
        }
    }

Poi un locationResult ..

public LocationResult locationResult = new LocationResult()
    {
        @Override
        public void gotLocation(final Location location)
        {
            currentLocation = new Location(location);
            hasLocation = true;
        }
    };

Inoltre, per evitare che si tira i capelli come ho fatto per secoli ricordarsi di interrompere l'attività locationcontrol Se le foglie qualcuno l'attività iniziali e anche aggiornamenti della posizione di arresto per fermare il GPS esecuzione quando le foglie degli utenti. In onStop () fare qualcosa di simile:

locHelper.stopLocationUpdates();
locationControlTask.cancel(true);

Anche stopLocationUpdates nella classe Location Helper fa il seguente:

public void stopLocationUpdates()
{
locationManager.removeUpdates(locationListenerGps);
locationManager.removeUpdates(locationListenerNetwork);
}

Buona fortuna con esso, ne avevo bisogno ...

Invece di creare un AsyncTask perché non hai crea una casella ProgressDialog e respingerlo su public void gotLocation(final Location location){}? È inoltre possibile aggiungere un onCancelListener alla casella ProgressDialog ed annullare eventuali richieste posizione corrente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top