Android 查找 GPS 位置一次,显示加载对话框

2024-04-25

我正在编写一个应用程序,它需要用户的当前位置(lastknownlocation 不会很有帮助)并显示从数据库中获取的所有最接近的“项目”的列表。

我已经找到了最近的项目,效果很好,但暂时只使用硬编码的纬度和经度位置,但现在是时候实现查找实际位置了。

任何人都可以提供一个示例,说明如何让应用程序在后台找到当前的精确位置并让应用程序等待。我只需要一次位置,不会随着人的移动而更新。我已经实现了一个位置侦听器,但我知道获取 GPS 修复可能会很慢。我见过其他使用最后已知位置或实现继续运行和更新的位置侦听器的示例,但是因为我的 Activity 需要位置坐标才能显示任何应用程序崩溃的内容。我需要在搜索时显示一个进度对话框。

如何让位置侦听器在后台运行一次,然后在找到位置后删除位置更新。我需要应用程序的其余部分等待,直到它有 GPS 位置或在 20-30 秒后超时。我想要一个 ProgressDialog,以便用户知道正在发生某些事情,但它必须是旋转加载动画而不是百分比或任何东西。如果可能的话,我希望用户能够取消对话框,如果他们厌倦了等待,那么他们可以通过输入郊区等进行搜索。

我一直在尝试用线程来做到这一点,但它变得比我想象的要复杂得多,而且仍然无法正常工作。在 iPhone 上这更简单?

任何人都可以提供一个很好的方法来做到这一点,我已经为此抓狂了一个星期,这确实让我落后于应用程序剩余完成日期的计划。

总之我想:
* 查找当前坐标
* 获取位置时显示进度对话框
* 应用程序是否能够等待成功定位或在一定时间后放弃?
* 如果成功:关闭进度对话框并使用坐标来运行我的其他方法来查找附近的项目。
* 如果无法获取位置:关闭进度对话框并显示错误消息,并鼓励用户使用菜单转到搜索活动。
* 如果用户从菜单中选择地图视图,则使用这些坐标,以显示地图上的当前位置,并使用数据库中的坐标在所有附近的项目上放置图钉。

谢谢大家,我希望我已经很好地解释了自己。如有任何问题,请提出,我会定期回来查看,因为我渴望完成这一部分。 干杯

EDIT
按要求编码

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

位置助手类

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

仅仅为了获取当前位置一次,这似乎真的是一个很大的努力?我不需要更新什么的?难道没有更简单的方法让应用程序等待结果吗?我已经被这个问题困扰了很长时间了。


Use an 异步任务并使用network_provider 和 gps_provider,这意味着两个听众。 GPS 需要更长的时间才能修复,有时可能需要一分钟,并且只能在户外使用,而网络获取位置的速度相当快。

一个很好的代码示例在这里:在 Android 上获取用户当前位置的最简单、最可靠的方法是什么? https://stackoverflow.com/questions/3145089/what-is-the-simplest-and-most-robust-way-to-get-the-users-current-location-in-an/3145655#3145655

对于 AsyncTask,请查看http://developer.android.com/reference/android/os/AsyncTask.html http://developer.android.com/reference/android/os/AsyncTask.html

这里还有很多代码示例,例如这里:Android 显示一个对话框,直到线程完成,然后继续程序 https://stackoverflow.com/questions/3430987/android-show-a-dialog-until-a-thread-is-done-and-then-continue-with-the-program/3431028#3431028

编辑: 代码概念:

添加类变量

boolean hasLocation = false;

在 onCreate 中调用(不在 AsyncTask 中):

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

然后在 locationListener.onLocationChanged 中,找到位置后更改值:

boolean hasLocation = false;

异步任务: 保持原样,但是不要打电话

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

在那里,而不是做

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

也许中间有一个延迟就足够了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 查找 GPS 位置一次,显示加载对话框 的相关文章

随机推荐