GPS定位一次

发布于 2024-11-08 22:30:06 字数 7814 浏览 4 评论 0原文

我有一个应用程序,它使用 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" /> 

如果有人愿意查看该错误,我将不胜感激。

I have an app that finds the users location (loading in a progress dialog) using GPS or network signal , when it finds it's location, the coordinates are written in a text view . If the GPS doesn't find a location in 40 sec or the user clicks on the cancel button , then the dialog closes. The problem is that if I click to cancel the dialog , it doesn't dismiss. However, if I click again, it dismisses. Why do I have to click twice ?!? Below is the source code:

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();
} 
}

The location helper:

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);
}
}

the 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>

and these 2 permissions in manifest

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

I would appreciate it if anyone would take a look at the bug.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉风有信 2024-11-15 22:30:06

我没有对您的代码进行深入分析,但您正在 onCreate 和 onStart 中启动 aysnc 任务。将其从其中之一中删除,因为我怀疑您只是将一个对话框放在另一个对话框之上。

I didn't do an in-depth analysis of your code, but you are starting the aysnc task in both onCreate and onStart. Remove it from one of those, because I suspect you simply have one dialog on top of the other.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文