Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android find GPS location once, show loading dialog

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.

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.

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.

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.

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.

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

EDIT
Code as requested

locationList activity file

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 class

    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.

like image 403
Daniel Bowden Avatar asked Aug 15 '10 03:08

Daniel Bowden


People also ask

What is Android location manager?

android.location.LocationManager. This class provides access to the system location services. These services allow applications to obtain periodic updates of the device's geographical location, or to be notified when the device enters the proximity of a given geographical location.

How to get current GPS location programmatically in Android?

This example demonstrates how do I get current GPS location programmatically in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main.xml

How do I find my current location on the map?

Tap “ My Location ” (the bulls-eye target icon). This should center the map on your phone’s current location Press and hold your finger on your current location that appears for more details The GPS coordinates of your position will appear followed by the address Once your location has been found, you can share it with others if you need to.

How does the GPs work on the device?

Think on the GPS as an element that you enable when waiting for locations and disable when you remove this listening. This behavior is done to avoid draining the user's battery. The time between you start listening and you receive the position depends on the device's GPS (manufacture, location of the user, satellite coverage...)

How do I Find my GPS coordinates on my phone?

If your phone comes equipped with a native compass, it will show up here. Next, depending on the compass app that your phone takes you to, you should see the GPS coordinates on the home screen. If not, you may have to click around the app to find them.


1 Answers

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.

A good code example is here: What is the simplest and most robust way to get the user's current location on Android?

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

There are also many code example here on SO for it, for example here: Android Show a dialog until a thread is done and then continue with the program

EDIT: code concept:

add class variable

boolean hasLocation = false; 

call in onCreate (not in AsyncTask):

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

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

boolean hasLocation = false; 

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.

like image 185
Mathias Conradt Avatar answered Oct 01 '22 16:10

Mathias Conradt