安卓发现GPS定位一次,显示加载对话框对话框、加载、发现、GPS

2023-09-12 07:02:51 作者:甜崽

我写一个应用程序,需要用户的当前位置(lastknownlocation不会有很大的帮助),并显示所有最靠近项目他们从数据库中采取的清单。

I am writing an app that requires the user's current location (lastknownlocation won't be very helpful) and displays a list of all the closest "items" to them taken from the database.

我已经得到了最近的项目发现工作很好,但只使用硬codeD所在位置的经纬度暂且但现在是时候实现寻找的实际位置。

I have got the finding of the closest items working well but only using a hardcoded latitude and longitude location for the time being but now it is time to implement finding the actual location.

任何人都可以提供如何具有该应用找到​​在后台的当前细位置和具有该应用等待一个例子。我只需要更新的位置,一旦没有人在移动。我实现了一个位置监听器,但是我明白得到一个GPS定位可能会很慢。我已经看到了使用最后一个已知位置或实现位置监听其继续运行,但更新我的活动所需要的位置坐标,才可以显示任何应用程序只是崩溃的其他例子。我需要显示一个进度对话框,而其搜索。

Can anyone provide an example of how to have the app find the current fine location in the background and have the app wait. I only need the location once not updates as the person moves. I have implemented a location listener however I understand getting a GPS fix can be slow. I have seen other examples using last known location or implementing the location listener which continues to run and update however as my Activity needs the location coordinates before it can display anything the app just crashes. I need to show a Progress Dialog while its searching.

我怎么能有LocationListener的运行一次的背景,然后删除位置更新,一旦它找到了位置。我需要的应用程序的其余部分要等到它有后一个GPS位置,或超时说20-30seconds。这样用户就知道的东西是怎么回事,但它只是必须是纺纱加载动画不到一个百分点或任何东西,我想一个ProgressDialog起来。如果可能的话我希望用户能够取消,如果他们生病的等待,然后他们可以通过键入郊区等,而不是搜索对话框。

How can I have the locationlistener run once in the background and then remove location updates once it finds the location. I need the rest of the application to wait until it has a GPS location or timeout after say 20-30seconds. I would like a ProgressDialog up so the user knows that something is going on, but it just has to be the spinning loading animation not a percentage or anything. If possible I would like the user to be able to cancel the dialog if they are sick of waiting which then they can search by typing suburb etc instead.

我一直在试图用线程做,但它越来越方式复杂得多,我觉得它应该是和仍然没有工作呢。在iPhone上,这是更简单吗?

I have been trying to do it with threads but it is getting way more complicated than I feel it should be and still not working anyway. On iPhone this is much more simple?

任何人都可以提供这样做的一个很好的方式,我一直在撕扯我的头发,一个星期就这个问题和它真的把我的进度落后于应用程序的完成日期的其余部分。

Can anyone provide a nice way of doing this, I have been ripping my hair out for a week on this and it is really putting me behind schedule for the rest of the app completion date.

在总结我想: *找到当前坐标 *显示进度对话框,同时获得位置 - *有应用程序能够等待成功的位置,或在一定时间后放弃? *如果成功的话:辞退进度对话框,并用坐标来运行我的其他方法寻找项​​目的closeby 。 *如果无法获得位置:辞退进度对话框并显示错误信息,并鼓励用户使用菜单中去搜寻活动。 *使用这些坐标,如果用户选择地图视图从菜单中,在地图上显示当前位置和引脚通过它们的坐标从数据库中删除所有附近的项目。

In summary I want to: * Find current coordinates * Show Progress Dialog while getting location * Have app be able to wait for successful location or give up after a certain time? * If Successful: Dismiss Progress Dialog and use coordinates to run my other methods for finding items closeby. * If Failed to get location: Dismiss Progress Dialog and show error message, and encourage user to use menu to go to Search Activity. * Use these coordinates if the user chooses map view from the menu, to show current location on the map and pins dropped at all the nearby items by using their coordinates from the database.

谢谢你们,我希望我已经解释自己不够好。如有任何问题只问,我会检查经常回来,因为我渴望得到这部分完成。 干杯

Thanks guys, I hope I have explained myself well enough. Any questions just ask, I will be checking back regularly as I am keen to get this part completed. Cheers

修改 根据要求code

EDIT Code as requested

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

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

这确实似乎是一个很大的努力只是为了获得当前位置一次?我并不需要更新或什么吗?请问有没有申请等待结果的一个更简单的方法?我一直停留在这这么久了。

This really seems like a big effort just to get the current location once? I do not require updates or anything? Is there not a simpler way of having the application wait for a result? I have been stuck on this for so long.

推荐答案

使用的的AsyncTask 并使用两个network_provider以及gps_provider ,这意味着两个监听器。 GPS需要较长的时间才能修复,也许有时一分钟,只适用于户外,而网络获得一个位置pretty的快。

Use an AsyncTask and use both network_provider as well as gps_provider, which means two listeners. gps takes longer to get a fix, maybe sometimes a minute and only works outdoors, while network gets a location pretty fast.

一个很好的code的例子是在这里:http://stackoverflow.com/questions/3145089/what-is-the-simplest-and-most-robust-way-to-get-the-users-current-location-in-an/3145655#3145655

A good code example is here: http://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

For AsyncTask, look http://developer.android.com/reference/android/os/AsyncTask.html

也有很多code例子在这里所以对于它,例如在这里: http://stackoverflow.com/questions/3430987/android-show-a-dialog-until-a-thread-is-done-and-then-continue-with-the-program/3431028#3431028

There are also many code example here on SO for it, for example here: http://stackoverflow.com/questions/3430987/android-show-a-dialog-until-a-thread-is-done-and-then-continue-with-the-program/3431028#3431028

编辑: code概念:

code concept:

添加类变量

boolean hasLocation = false;

在的onCreate(而不是在AsyncTask的)电话:

call in onCreate (not in AsyncTask):

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

然后locationListener.onLocationChanged,一旦位置被发现更改值:

then in locationListener.onLocationChanged, change the value once a location is found:

boolean hasLocation = false;

AsyncTask的: 离开,因为它是,但不叫

AsyncTask: leave as it is, but don't call

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

在那里,而不是做

there, instead do

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

可能与一个延迟之间就足够了。

probably with a delay in between would be sufficient.