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

Dan*_*den 26 gps android progressdialog locationlistener

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

我发现最近的项目运行良好,但目前仅使用硬编码的纬度和经度位置,但现在是时候实现查找实际位置了.

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

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

我一直试图用线程做到这一点,但它变得比我觉得应该更复杂,但仍然无法工作.在iPhone上这更简单了吗?

任何人都可以提供一个很好的方法来做到这一点,我已经把我的头发扯了一个星期,这真的让我落后于应用程序完成日期的剩余时间.

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

谢谢你们,我希望我能够很好地解释自己.如有任何问题,我会定期回来查看,因为我很想完成这部分.干杯


根据要求编辑代码

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;
    }
};  
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这真的似乎只是为了获得当前位置一次?我不需要更新或任何其他内容?是否有更简单的方法让应用程序等待结果?我已经坚持这么久了.

Mat*_*adt 16

使用AsyncTask并使用network_provider和gps_provider,这意味着两个侦听器.gps需要更长时间才能获得修复,有时可能只需要一分钟,只能在室外工作,而网络可以快速获得位置.

这里有一个很好的代码示例:在Android上获取用户当前位置的最简单,最强大的方法是什么?

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

这里还有许多代码示例,例如: Android在线程完成之前显示一个对话框,然后继续执行该程序

编辑:代码概念:

添加类变量

boolean hasLocation = false;
Run Code Online (Sandbox Code Playgroud)

调用onCreate(不在AsyncTask中):

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
Run Code Online (Sandbox Code Playgroud)

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

boolean hasLocation = false;
Run Code Online (Sandbox Code Playgroud)

AsyncTask:保持原样,但不要打电话

LocationHelper location = new LocationHelper();
location.getLocation(params[0], locationResult);
Run Code Online (Sandbox Code Playgroud)

在那里,而是做

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

可能延迟介于两者之间就足够了.


Dan*_*den 12

我仍然不喜欢它是如何工作的,它看起来比它应该更复杂但是直到某人提供了一种更好的方式我现在正在工作......

如果有人遇到这个并提出一个更好的清洁结果,只需获取用户当前的位置坐标,然后停止查看,将非常感谢!!

private LocationControl locationControlTask;
private boolean hasLocation = false;
LocationHelper locHelper;
Run Code Online (Sandbox Code Playgroud)

从onCreate()我打电话

locHelper = new LocationHelper();
locHelper.getLocation(context, locationResult);
locationControlTask = new LocationControl();
locationControlTask.execute(this);
Run Code Online (Sandbox Code Playgroud)

然后我有一个私人类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
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后是locationResult ..

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

另外,为了避免你像我多年来一样拔出头发,请记住如果有人提前离开活动,请停止位置控制任务,并停止位置更新以阻止GPS在用户离开时运行.在onStop()中执行以下操作:

locHelper.stopLocationUpdates();
locationControlTask.cancel(true);
Run Code Online (Sandbox Code Playgroud)

另外,Location Helper类中的stopLocationUpdates执行以下操作:

public void stopLocationUpdates()
{
locationManager.removeUpdates(locationListenerGps);
locationManager.removeUpdates(locationListenerNetwork);
}
Run Code Online (Sandbox Code Playgroud)

祝你好运,我需要它......

  • 发布完整的工作代码(即github)对你和我们来说都很棒:) (7认同)