GPS местоположение один раз - PullRequest
1 голос
/ 21 мая 2011

У меня есть приложение, которое находит местоположение пользователя (загрузка в диалоговом окне прогресса) с помощью 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" /> 

Буду признателен, если кто-нибудь взглянет на ошибку.

1 Ответ

1 голос
/ 21 мая 2011

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

...