GPS местоположение один раз

1

У меня есть приложение, которое находит местоположение пользователя (загрузка в диалоговом окне прогресса) с использованием GPS или сетевого сигнала, когда он находит его местоположение, координаты записываются в текстовом виде. Если GPS не находит местоположение за 40 секунд или пользователь нажимает кнопку отмены, диалог закрывается. Проблема в том, что если я нажму, чтобы отменить диалог, он не будет отклонен. Однако, если я снова нажму, он отклоняется. Почему я должен дважды щелкнуть?!? Ниже приведен исходный код:

public class MainActivity extends Activity {
private LocationControl locationControlTask;
private boolean hasLocation = false;
LocationHelper locHelper;
protected Location currentLocation;
private TextView myText;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    myText = (TextView)findViewById(R.id.mytext);

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


}

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

    // ....

    new LocationControl().execute(this);
}

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


    protected void onPreExecute()
    {
        this.dialog.setMessage("Tap to cancel");
        this.dialog.setTitle("Searching");
        this.dialog.setCancelable(true);  
        this.dialog.setButton(Dialog.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {             
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if(which == Dialog.BUTTON_NEGATIVE) {
                    dialog.dismiss();
                    Toast.makeText(MainActivity.this, "dialog canceled", Toast.LENGTH_SHORT).show();
                }
            }
        });
        this.dialog.show();

    }

    protected Void doInBackground(Context... params)
    {
        //Wait 40 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 < 40000) {
            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();
            String text = "lat:"+currentLocation.getLatitude()+" long:"+currentLocation.getLongitude();
            myText.setText(text);
        }
        else
        {
            Toast.makeText(MainActivity.this, "location could not be found", Toast.LENGTH_SHORT).show();

            //Couldn't find location, do something like show an alert dialog
        }
    }
}

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

@Override
protected void onStop() {
    locHelper.stopLocationUpdates();
    locationControlTask.cancel(true);
    super.onStop();
} 
}

Помощник местоположения:

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)
        {   //if()
            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 void stopLocationUpdates() {
    locationManager.removeUpdates(locationListenerGps);
    locationManager.removeUpdates(locationListenerNetwork);
}


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

xml:

<?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView
      android:id="@+id/mytext"  
      android:textSize="15dip"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:text="Main activity"/>
  </LinearLayout>

и эти 2 разрешения в манифесте

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

Я был бы признателен, если бы кто-нибудь посмотрел на ошибку.

  • 0
    Сделайте отступ в своем коде и пометьте часть XML как код, чтобы вопрос был читабельным.
Теги:
location
progress
gps
dialog

1 ответ

1
Лучший ответ

Я не проводил подробный анализ вашего кода, но вы начинаете задачу aysnc как в onCreate, так и onStart. Удалите его из одного из них, потому что я подозреваю, что у вас просто один диалог поверх другого.

  • 2
    спасибо, вы правы, я открыл диалог дважды. Я удалил его из onCreate (), но означает ли это, что всякий раз, когда приложение переходит в фоновый режим или приостанавливается, и через некоторое время, если пользователь снова возвращается в приложение, вызывается onStart (), или мне следует реализовать onResume?
  • 0
    Я не уверен, почему ваш диалог существует, поэтому немного сложно ответить на этот вопрос. Если диалоговое окно показывалось до того, как действие было прекращено (и действие не уничтожено), оно все равно должно отображаться, когда вы вернетесь (не предпринимая никаких действий). Если действие убито, то любая функция, в которой у вас есть открытый код, покажет его снова (создание, запуск или возобновление). Хитрость заключается в том, чтобы диалоговое окно не отображалось повторно (если пользователь закрыл его перед тем, как покинуть ваше приложение) после ситуации, требующей уничтожения экземпляра вашей активности.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню