2010-06-29 4 views
690

API-интерфейс LocationManager на Android выглядит так, как будто это боль в использовании для приложения, которому требуется только случайное и грубое приближение местоположения пользователя.Что такое самый простой и надежный способ получить текущее местоположение пользователя на Android?

Приложение, над которым я работаю, на самом деле не является приложением местоположения, но ему нужно получить местоположение пользователя, чтобы отобразить список ближайших предприятий. Не нужно беспокоиться о том, перемещается ли пользователь или что-то в этом роде.

Вот что я хотел бы сделать:

  1. показать пользователю список близлежащих мест.
  2. Предварительно загрузите местоположение пользователя, чтобы к моменту, когда он мне понадобится, в Activity X, он будет доступен.
  3. Меня не особенно волнует точность или частота обновления. Достаточно хватать одно место, пока это не выход. Может быть, если я хочу быть фантазией, я обновляю местоположение каждые несколько минут или около того, но это не очень важный приоритет.
  4. Работайте на любом устройстве, если у него есть GPS или поставщик сетевого местоположения.

Кажется, что это не должно быть так сложно, но мне кажется, что мне нужно развернуть двух разных поставщиков местоположения (GPS и NETWORK) и управлять жизненным циклом каждого из них. Не только это, но я должен дублировать один и тот же код в нескольких действиях, чтобы удовлетворить # 2. Я пытался использовать getBestProvider() в прошлом, чтобы сократить решение до простого использования одного провайдера местоположения, но это, кажется, дает вам лучший «теоретический» провайдер, а не поставщик, который на самом деле даст вам наилучшие результаты.

Есть ли более простой способ достичь этого?

+5

[Здесь] (http://rdcworld-android.blogspot.in/2012/01/get-current-location-coordinates-city.html) вы можете найти пошаговое руководство с образцом кода для GPS, ура! – swiftBoy

+0

Вы можете использовать простую библиотеку, которая абстрагирует все вещи, которые должны произойти «под капотом»: https://github.com/delight-im/Android-SimpleLocation – caw

ответ

851

Вот что я делаю:

  1. Прежде всего я проверяю, что провайдеры включены. Некоторые могут быть отключены на устройстве, некоторые могут быть отключены в манифесте приложения.
  2. Если у вас есть какой-либо провайдер, я запускаю приемники местоположения и таймер тайм-аута. Это 20 секунд в моем примере, может быть недостаточно для GPS, поэтому вы можете увеличить его.
  3. Если я получаю обновление из приемника местоположения, я использую предоставленное значение. Я останавливаю слушателей и таймер.
  4. Если я не получаю никаких обновлений и таймеров, я должен использовать последние известные значения.
  5. Я беру последние известные значения у доступных поставщиков и выбираю самые последние из них.

Вот как я использую мой класс:

LocationResult locationResult = new LocationResult(){ 
    @Override 
    public void gotLocation(Location location){ 
     //Got the location! 
    } 
}; 
MyLocation myLocation = new MyLocation(); 
myLocation.getLocation(this, locationResult); 

А вот MyLocation класс:

import java.util.Timer; 
import java.util.TimerTask; 
import android.content.Context; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 

public class MyLocation { 
    Timer timer1; 
    LocationManager lm; 
    LocationResult locationResult; 
    boolean gps_enabled=false; 
    boolean network_enabled=false; 

    public boolean getLocation(Context context, LocationResult result) 
    { 
     //I use LocationResult callback class to pass location value from MyLocation to user code. 
     locationResult=result; 
     if(lm==null) 
      lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 

     //exceptions will be thrown if provider is not permitted. 
     try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){} 
     try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){} 

     //don't start listeners if no provider is enabled 
     if(!gps_enabled && !network_enabled) 
      return false; 

     if(gps_enabled) 
      lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps); 
     if(network_enabled) 
      lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork); 
     timer1=new Timer(); 
     timer1.schedule(new GetLastLocation(), 20000); 
     return true; 
    } 

    LocationListener locationListenerGps = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      timer1.cancel(); 
      locationResult.gotLocation(location); 
      lm.removeUpdates(this); 
      lm.removeUpdates(locationListenerNetwork); 
     } 
     public void onProviderDisabled(String provider) {} 
     public void onProviderEnabled(String provider) {} 
     public void onStatusChanged(String provider, int status, Bundle extras) {} 
    }; 

    LocationListener locationListenerNetwork = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      timer1.cancel(); 
      locationResult.gotLocation(location); 
      lm.removeUpdates(this); 
      lm.removeUpdates(locationListenerGps); 
     } 
     public void onProviderDisabled(String provider) {} 
     public void onProviderEnabled(String provider) {} 
     public void onStatusChanged(String provider, int status, Bundle extras) {} 
    }; 

    class GetLastLocation extends TimerTask { 
     @Override 
     public void run() { 
      lm.removeUpdates(locationListenerGps); 
      lm.removeUpdates(locationListenerNetwork); 

      Location net_loc=null, gps_loc=null; 
      if(gps_enabled) 
       gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
      if(network_enabled) 
       net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

      //if there are both values use the latest one 
      if(gps_loc!=null && net_loc!=null){ 
       if(gps_loc.getTime()>net_loc.getTime()) 
        locationResult.gotLocation(gps_loc); 
       else 
        locationResult.gotLocation(net_loc); 
       return; 
      } 

      if(gps_loc!=null){ 
       locationResult.gotLocation(gps_loc); 
       return; 
      } 
      if(net_loc!=null){ 
       locationResult.gotLocation(net_loc); 
       return; 
      } 
      locationResult.gotLocation(null); 
     } 
    } 

    public static abstract class LocationResult{ 
     public abstract void gotLocation(Location location); 
    } 
} 

Кто-то, возможно, также хотят, чтобы изменить мою логику. Например, если вы получаете обновление от поставщика сети, не останавливайте слушателей, а продолжайте ждать. GPS дает более точные данные, поэтому стоит его ждать. Если таймер истекает, и у вас есть обновление от Сети, но не от GPS, вы можете использовать значение, предоставляемое из сети.

Еще один подход - использовать LocationClient http://developer.android.com/training/location/retrieve-current.html. Но для этого на устройстве пользователя необходимо установить apk Google Play Services.

+2

Hi Fedor , спасибо за это, он выглядит поразительно похожим на то, что я делал для предыдущих проектов. И это более или менее то, что подтолкнуло этот вопрос: наверняка должен быть более простой способ ?! – emmby

+0

Я не знаю более простого способа. Вы можете внести изменения в мой метод. Например, вы можете слушать только одного провайдера вместо двух. Но в любом случае вам нужен слушатель, таймер тайм-аута. – Fedor

+0

Правильно. «android: configChanges» следует указать, чтобы избежать перезапуска активности при изменении ориентации. И если вам все равно нужно перезапустить активность, вы должны отменить TimerTask или даже полный таймер. – Fedor

8

Вы всегда можете использовать LocationManager.getLastKnownLocation(), но, как говорится, он может быть устаревшим.

И простой способ получить общее местоположение можно зарегистрировать для сети (обычно довольно быстро).

LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
locationManager.requestLocationUpdates(
    LocationManager.NETWORK_PROVIDER, 1000, 1000, this); 

, а затем делать

locationManager.removeUpdates(this); 

в onLocationChanged() методе слушателя.

+0

Спасибо BrennaSoft. Я обнаружил, что getLastKnownLocation() часто может быть безумно выключен и, следовательно, не работает как автономное решение. Кроме того, мне непонятно, что работа с NETWORK_PROVIDER будет работать, поскольку многие районы страны не имеют очень хороших GPS-координат для точек доступа Wi-Fi (и я не знаю о сотовых башнях). – emmby

+0

Для поиска наиболее актуального местоположения вы также можете рассмотреть этот [пример получения последнего места в android] (http://android.codota.com/scenarios/528e1ea2da0ae208e8c01cf7/LocationManager.getLastKnownLocation?tag=bumblebee) – drorw

5

Я не уверен, если Location-Based Services может получить место от другой, отличной от GPS инфраструктуры, но в соответствии с этой статьей, это представляется возможным:

Приложение может позвонить по любому из нескольких типов позиционирования методы.

Использование сети мобильного телефона: тока идентификатор соты может быть использован для идентификации базовой приемопередающей станции (BTS), что устройство обменивается данными с и расположение этой БППС. Ясно, что точность этого метода зависит от размера ячейки, а может быть довольно неточной. Ячейка GSM может составлять от 2 до 20 километров в диаметре.Другие методы , используемые вместе с идентификатором ячейки, могут достичь точности в пределах 150 метров.

Using satellites: Global Positioning System (GPS), controlled by в Department US of Defense, uses a constellation of 24 satellites orbiting в earth. GPS определяет положение устройства , вычисляя разницу во времени от различных спутников, чтобы добраться до приемника . Сигналы GPS кодируются, поэтому мобильное устройство должно быть оборудовано с приемником GPS. GPS является потенциально наиболее точный метод (от 4 до 40 метров, если приемник GPS имеет четкое представление о небе), но она имеет некоторые недостатки: Дополнительное оборудование может быть дорогостоящим, потребляет батареи во время использования , и требует некоторого разогрева после холодного запуска, чтобы получить первоначальное исправление на видимых спутниках. Он также страдает от «эффектов каньона» в городах, где видимость спутника является прерывистой.

Использование малого радиуса действия позиционирования маяки: в относительно небольших областях, таких как единый здания, локальная сеть может обеспечить местоположения наряду с другими услуг. Например, соответствующим образом оборудованные устройства могут использовать Bluetooth для ближнего позиционирования.

+1

@ElijahSaounkine, по-видимому, npinti не слышал об Assisted GPS. В будущем вы могли бы просто сообщить людям о вещах, над которыми они наблюдали, вместо того, чтобы быть агрессивными. – saltandpepper

+0

@Sammy 5 лет назад Я, кажется, был намного более нервным, чем сейчас. «Будущее», о котором вы говорите, по отношению к моей заметке, возможно, уже началось и закончилось;) –

4

Фактически мы можем использовать обоих поставщиков обоих.И они просто разделяют общественный слушателю:

locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10 * 1000, (float) 10.0, listener); 
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 90 * 1000, (float) 10.0, listener); 

Это необходимо, так как метод OnLocationChanged() всегда нужно назвать временем.

2

Чтобы получить и показать текущее местоположение пользователя, вы также можете использовать MyLocationOverlay. Предположим, у вас есть поле mapView в вашей деятельности. Все, что вам нужно будет сделать, чтобы показать местоположение пользователя является следующее:

myLocationOverlay = new MyLocationOverlay(this, mapView); 
myLocationOverlay.enableMyLocation(); 
mapView.getOverlays().add(myLocationOverlay); 

Это получает текущее местоположение либо GPS или сети. Если оба отказа, enableMyLocation() вернется false.

Что касается местоположения предметов вокруг этого района, то необходимо сделать так, чтобы ItemizedOverlay.

Надеюсь, я не понял ваш вопрос неправильно. Удачи.

+2

Спасибо. Вопрос касался действий, которые не имеют вид на карту, и не нужно отображать местоположение для пользователя. – emmby

35

После поиска лучшей реализации, как получить лучшее точное местоположение пользователя, мне удалось объединить все самые лучшие методы и придумали следующий класс:

/** 
* Retrieve accurate location from GPS or network services. 
* 
* 
* Class usage example: 
* 
* public void onCreate(Bundle savedInstanceState) { 
*  ... 
*  my_location = new MyLocation(); 
*  my_location.init(main.this, locationResult); 
* } 
* 
* 
* public LocationResult locationResult = new LocationResult(){ 
*  @Override 
*  public void gotLocation(final Location location){ 
*   // do something 
*   location.getLongitude(); 
*   location.getLatitude(); 
*  } 
* }; 
*/ 
class MyLocation{ 

    /** 
    * If GPS is enabled. 
    * Use minimal connected satellites count. 
    */ 
    private static final int min_gps_sat_count = 5; 

    /** 
    * Iteration step time. 
    */ 
    private static final int iteration_timeout_step = 500; 

    LocationResult locationResult; 
    private Location bestLocation = null; 
    private Handler handler = new Handler(); 
    private LocationManager myLocationManager; 
    public Context context; 

    private boolean gps_enabled = false; 

    private int counts = 0; 
    private int sat_count = 0; 

    private Runnable showTime = new Runnable() { 

     public void run() { 
      boolean stop = false; 
      counts++; 
      System.println("counts=" + counts); 

      //if timeout (1 min) exceeded, stop tying 
      if(counts > 120){ 
       stop = true; 
      } 

      //update last best location 
      bestLocation = getLocation(context); 

      //if location is not ready or don`t exists, try again 
      if(bestLocation == null && gps_enabled){ 
       System.println("BestLocation not ready, continue to wait"); 
       handler.postDelayed(this, iteration_timeout_step); 
      }else{ 
       //if best location is known, calculate if we need to continue to look for better location 
       //if gps is enabled and min satellites count has not been connected or min check count is smaller then 4 (2 sec) 
       if(stop == false && !needToStop()){ 
        System.println("Connected " + sat_count + " sattelites. continue waiting.."); 
        handler.postDelayed(this, iteration_timeout_step); 
       }else{ 
        System.println("#########################################"); 
        System.println("BestLocation finded return result to main. sat_count=" + sat_count); 
        System.println("#########################################"); 

        // removing all updates and listeners 
        myLocationManager.removeUpdates(gpsLocationListener); 
        myLocationManager.removeUpdates(networkLocationListener);  
        myLocationManager.removeGpsStatusListener(gpsStatusListener); 
        sat_count = 0; 

        // send best location to locationResult 
        locationResult.gotLocation(bestLocation); 
       } 
      } 
     } 
    }; 

    /** 
    * Determine if continue to try to find best location 
    */ 
    private Boolean needToStop(){ 

     if(!gps_enabled){ 
          return true; 
        } 
      else if(counts <= 4){ 
       return false; 
      } 
      if(sat_count < min_gps_sat_count){ 
       //if 20-25 sec and 3 satellites found then stop 
       if(counts >= 40 && sat_count >= 3){ 
        return true; 
       } 
       return false; 
      } 
     } 
     return true; 
    } 

    /** 
    * Best location abstract result class 
    */ 
    public static abstract class LocationResult{ 
     public abstract void gotLocation(Location location); 
    } 

    /** 
    * Initialize starting values and starting best location listeners 
    * 
    * @param Context ctx 
    * @param LocationResult result 
    */ 
    public void init(Context ctx, LocationResult result){ 
     context = ctx; 
     locationResult = result; 

     myLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 

     gps_enabled = (Boolean) myLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 

     bestLocation = null; 
     counts = 0; 

     // turning on location updates 
     myLocationManager.requestLocationUpdates("network", 0, 0, networkLocationListener); 
     myLocationManager.requestLocationUpdates("gps", 0, 0, gpsLocationListener); 
     myLocationManager.addGpsStatusListener(gpsStatusListener); 

     // starting best location finder loop 
     handler.postDelayed(showTime, iteration_timeout_step); 
    } 

    /** 
    * GpsStatus listener. OnChainged counts connected satellites count. 
    */ 
    public final GpsStatus.Listener gpsStatusListener = new GpsStatus.Listener() { 
     public void onGpsStatusChanged(int event) { 

      if(event == GpsStatus.GPS_EVENT_SATELLITE_STATUS){ 
       try { 
        // Check number of satellites in list to determine fix state 
        GpsStatus status = myLocationManager.getGpsStatus(null); 
        Iterable<GpsSatellite>satellites = status.getSatellites(); 

        sat_count = 0; 

        Iterator<GpsSatellite>satI = satellites.iterator(); 
        while(satI.hasNext()) { 
         GpsSatellite satellite = satI.next(); 
         System.println("Satellite: snr=" + satellite.getSnr() + ", elevation=" + satellite.getElevation());       
         sat_count++; 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
        sat_count = min_gps_sat_count + 1; 
       } 

       System.println("#### sat_count = " + sat_count); 
      } 
     } 
    }; 

    /** 
    * Gps location listener. 
    */ 
    public final LocationListener gpsLocationListener = new LocationListener(){ 
     @Override 
     public void onLocationChanged(Location location){ 

     } 
     public void onProviderDisabled(String provider){} 
     public void onProviderEnabled(String provider){} 
     public void onStatusChanged(String provider, int status, Bundle extras){} 
    }; 

    /** 
    * Network location listener. 
    */ 
    public final LocationListener networkLocationListener = new LocationListener(){ 
     @Override 
     public void onLocationChanged(Location location){ 

     } 
     public void onProviderDisabled(String provider){} 
     public void onProviderEnabled(String provider){} 
     public void onStatusChanged(String provider, int status, Bundle extras){} 
    }; 


    /** 
    * Returns best location using LocationManager.getBestProvider() 
    * 
    * @param context 
    * @return Location|null 
    */ 
    public static Location getLocation(Context context){ 
     System.println("getLocation()"); 

     // fetch last known location and update it 
     try { 
      LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 

      Criteria criteria = new Criteria(); 
      criteria.setAccuracy(Criteria.ACCURACY_FINE); 
      criteria.setAltitudeRequired(false); 
      criteria.setBearingRequired(false); 
      criteria.setCostAllowed(true); 
      String strLocationProvider = lm.getBestProvider(criteria, true); 

      System.println("strLocationProvider=" + strLocationProvider); 
      Location location = lm.getLastKnownLocation(strLocationProvider); 
      if(location != null){ 
       return location; 
      } 
      return null; 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 
} 

Этот класс пытается подключиться к min_gps_sat_count спутников, если GPS включена , Else возвращает LocationManager.getBestProvider(). Проверьте код!

+0

Thanx для кода, я пытаюсь. Первый вопрос: как его остановить? – Maep

+2

Он остановится через 1 минуту или когда он найдет место. – wormhit

+0

у вас все еще есть этот код? могу ли вы отправить его мне? ? это моя электронная почта. [email protected] спасибо за продвижение. –

26

С решением Fedor я испытал множественное выполнение обратного вызова gotLocation. Кажется, что из-за условия гонки в переопределенном методе LocationListener.onLocationChanged, когда gotLocation метод 'достаточно долго'. Я не уверен, но я предполагаю, что removeUpdates предотвращает появление новых сообщений в очереди Looper, но не удаляет уже запущенные, но еще не потребленные. Следовательно, состояние гонки.

Чтобы уменьшить вероятность этого неправильного поведения, вы можете вызвать removeUpdates перед запуском события onLocationChanged, но все же у нас есть условие гонки.

Лучшее решение, которое я нашел, это заменить requestLocationUpdates на requestSingleUpdate.

Это моя версия, основанная на решении Федора, используя обработчик для отправки сообщения нити петлителя:

public class LocationResolver { 
    private Timer timer; 
    private LocationManager locationManager; 
    private LocationResult locationResult; 
    private boolean gpsEnabled = false; 
    private boolean networkEnabled = false; 
    private Handler locationTimeoutHandler; 

    private final Callback locationTimeoutCallback = new Callback() { 
     public boolean handleMessage(Message msg) { 
      locationTimeoutFunc(); 
      return true; 
     } 

     private void locationTimeoutFunc() { 
      locationManager.removeUpdates(locationListenerGps); 
      locationManager.removeUpdates(locationListenerNetwork); 

      Location networkLocation = null, gpsLocation = 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);   
     } 
    }; 
    private final LocationListener locationListenerGps = new LocationListener() { 
     public void onLocationChanged(Location location) {    
      timer.cancel(); 
      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 extras) { 
     } 
    }; 
    private final LocationListener locationListenerNetwork = new LocationListener() { 
     public void onLocationChanged(Location location) {  
      timer.cancel(); 
      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 extras) { 
     } 
    }; 

    public void prepare() { 
     locationTimeoutHandler = new Handler(locationTimeoutCallback); 
    } 

    public synchronized boolean getLocation(Context context, LocationResult result, int maxMillisToWait) { 
     locationResult = result; 
     if (locationManager == null) 
      locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 

     // exceptions will be thrown if provider is not permitted. 
     try { 
      gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
     } catch (Exception ex) { 
     } 
     try { 
      networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     } catch (Exception ex) { 
     } 

     // don't start listeners if no provider is enabled 
     if (!gpsEnabled && !networkEnabled) 
      return false; 

     if (gpsEnabled) 
      locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, locationListenerGps, Looper.myLooper()); 
      //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps); 
     if (networkEnabled) 
      locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, locationListenerNetwork, Looper.myLooper()); 
      //locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork); 

     timer = new Timer(); 
     timer.schedule(new GetLastLocationTask(), maxMillisToWait); 
     return true; 
    } 

    private class GetLastLocationTask extends TimerTask { 
     @Override 
     public void run() { 
      locationTimeoutHandler.sendEmptyMessage(0); 
     } 
    } 

    public static abstract class LocationResult { 
     public abstract void gotLocation(Location location); 
    } 
} 

Я использую этот класс от настраиваемой нити петлителя, как следующему:

public class LocationGetter { 
    private final Context context; 
    private Location location = null; 
    private final Object gotLocationLock = new Object(); 
    private final LocationResult locationResult = new LocationResult() {    
     @Override 
     public void gotLocation(Location location) { 
      synchronized (gotLocationLock) { 
       LocationGetter.this.location = location; 
       gotLocationLock.notifyAll(); 
       Looper.myLooper().quit(); 
      } 
     } 
    }; 

    public LocationGetter(Context context) { 
     if (context == null) 
      throw new IllegalArgumentException("context == null"); 

     this.context = context; 
    } 

    public synchronized Coordinates getLocation(int maxWaitingTime, int updateTimeout) { 
     try { 
      final int updateTimeoutPar = updateTimeout; 
      synchronized (gotLocationLock) {    
       new Thread() { 
        public void run() { 
         Looper.prepare(); 
         LocationResolver locationResolver = new LocationResolver(); 
         locationResolver.prepare(); 
         locationResolver.getLocation(context, locationResult, updateTimeoutPar); 
         Looper.loop(); 
        } 
       }.start(); 

       gotLocationLock.wait(maxWaitingTime); 
      } 
     } catch (InterruptedException e1) { 
      e1.printStackTrace(); 
     } 

     if (location != null) 
      coordinates = new Coordinates(location.getLatitude(), location.getLongitude()); 
     else 
      coordinates = Coordinates.UNDEFINED; 
     return coordinates; 
    } 
} 

где координаты - это простой класс с двумя свойствами: широтой и долготой.

+4

Интересный момент, во всяком случае, requestSingleUpdate требует API уровня 9. Но +1 для указания этого. – Eduardo

+0

@Eduardo: еще одна возможность - выполнить код задачи с помощью обработчика, связанного с петлеукладчиком, и вызвать его, отправив (пустое) сообщение обработчику. Поскольку сообщения сериализуются в очереди петлителя, вы можете удалить вручную (например, с помощью флага) состояние гонки. Для этого не требуется API Livel 9, но он должен явно использовать петлитель. – differenziale

+0

@differenziale Ваш код более совершенен, но я не могу использовать его в своем проекте. Если вы можете немного разобраться с классом Activity, то я буду более чем счастлив рассказать вам. –

5

Используйте приведенный ниже код, это даст лучший поставщик доступных:

String locCtx = Context.LOCATION_SERVICE; 

LocationManager locationMgr = (LocationManager) ctx.getSystemService(locCtx); 

Criteria criteria = new Criteria(); 
criteria.setAccuracy(Criteria.ACCURACY_FINE); 
criteria.setAltitudeRequired(false); 
criteria.setBearingRequired(false); 
criteria.setCostAllowed(true); 
criteria.setPowerRequirement(Criteria.POWER_LOW); 

String provider = locationMgr.getBestProvider(criteria, true); 

System.out.println("Best Available provider::::"+provider); 
+0

как инициализировать ctx, Context ctx = this;? Crashed – 2015-11-29 13:14:35

15

я создал небольшое приложение с пошаговым описанием к получает текущие местоположения GPS координаты.

enter image description here

Полный пример исходного кода в URL ниже:


Get Current Location coordinates , City name - in Android


Посмотрите, как это работает:

  • Все, что нам нужно сделать, это добавить это разрешение в файле манифеста

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"> 
    </uses-permission> 
    
  • и создать LocationManager экземпляр, как этот

    LocationManager locationManager = (LocationManager) 
                getSystemService(Context.LOCATION_SERVICE); 
    
  • Check GPS включен или нет

  • затем реализовать LocationListener и получить координаты

    LocationListener locationListener = new MyLocationListener(); 
    locationManager.requestLocationUpdates( 
    LocationManager.GPS_PROVIDER, 5000, 10, locationListener); 
    
  • здесь пример кода, чтобы сделать


/*----------Listener class to get coordinates ------------- */ 
private class MyLocationListener implements LocationListener { 

    @Override 
    public void onLocationChanged(Location loc) { 
     editLocation.setText(""); 
     pb.setVisibility(View.INVISIBLE); 
     Toast.makeText(
      getBaseContext(), 
      "Location changed: Lat: " + loc.getLatitude() + " Lng: " 
       + loc.getLongitude(), Toast.LENGTH_SHORT).show(); 
     String longitude = "Longitude: " + loc.getLongitude(); 
     Log.v(TAG, longitude); 
     String latitude = "Latitude: " + loc.getLatitude(); 
     Log.v(TAG, latitude); 
     /*-------to get City-Name from coordinates -------- */ 
     String cityName = null; 
     Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault()); 
     List<Address> addresses; 
     try { 
      addresses = gcd.getFromLocation(loc.getLatitude(), 
       loc.getLongitude(), 1); 
      if (addresses.size() > 0) 
       System.out.println(addresses.get(0).getLocality()); 
      cityName = addresses.get(0).getLocality(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     String s = longitude + "\n" + latitude + "\n\nMy Current City is: " 
      + cityName; 
     editLocation.setText(s); 
    } 

    @Override 
    public void onProviderDisabled(String provider) {} 

    @Override 
    public void onProviderEnabled(String provider) {} 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) {} 
} 
+0

местоположение должно быть изменено, а не стоять – 2015-11-29 12:54:14

3

Это код, который обеспечивает текущий пользовательский местоположение

создать Аккаунт Карты:

public class Maps extends MapActivity { 

    public static final String TAG = "MapActivity"; 
    private MapView mapView; 
    private LocationManager locationManager; 
    Geocoder geocoder; 
    Location location; 
    LocationListener locationListener; 
    CountDownTimer locationtimer; 
    MapController mapController; 
    MapOverlay mapOverlay = new MapOverlay(); 

    @Override 
    protected void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     setContentView(R.layout.main); 
     initComponents(); 
     mapView.setBuiltInZoomControls(true); 
     mapView.setSatellite(true); 
     mapView.setTraffic(true); 
     mapView.setStreetView(true); 
     mapController = mapView.getController(); 
     mapController.setZoom(16); 
     locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); 
     if (locationManager == null) { 
      Toast.makeText(Maps.this, "Location Manager Not Available", 
       Toast.LENGTH_SHORT).show(); 
      return; 
     } 
     location = locationManager 
       .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
     if (location == null) 
      location = locationManager 
        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
     if (location != null) { 
      double lat = location.getLatitude(); 
      double lng = location.getLongitude(); 
      Toast.makeText(Maps.this, "Location Are" + lat + ":" + lng, 
       Toast.LENGTH_SHORT).show(); 
      GeoPoint point = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6)); 
      mapController.animateTo(point, new Message()); 
      mapOverlay.setPointToDraw(point); 
      List<Overlay> listOfOverlays = mapView.getOverlays(); 
      listOfOverlays.clear(); 
      listOfOverlays.add(mapOverlay); 
     } 
     locationListener = new LocationListener() { 

      public void onStatusChanged(String arg0, int arg1, Bundle arg2) {} 

      public void onProviderEnabled(String arg0) {} 

      public void onProviderDisabled(String arg0) {} 

      public void onLocationChanged(Location l) { 
       location = l; 
       locationManager.removeUpdates(this); 
       if (l.getLatitude() == 0 || l.getLongitude() == 0) { 
       } else { 
        double lat = l.getLatitude(); 
        double lng = l.getLongitude(); 
        Toast.makeText(Maps.this, "Location Are" + lat + ":" + lng, 
         Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }; 
     if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) 
      locationManager.requestLocationUpdates(
       LocationManager.GPS_PROVIDER, 1000, 10f, locationListener); 
     locationManager.requestLocationUpdates(
      LocationManager.NETWORK_PROVIDER, 1000, 10f, locationListener); 
     locationtimer = new CountDownTimer(30000, 5000) { 

      @Override 
      public void onTick(long millisUntilFinished) { 
       if (location != null) locationtimer.cancel(); 
      } 

      @Override 
      public void onFinish() { 
       if (location == null) { 
       } 
      } 
     }; 
     locationtimer.start(); 
    } 

    public MapView getMapView() { 
     return this.mapView; 
    } 

    private void initComponents() { 
     mapView = (MapView) findViewById(R.id.map_container); 
     ImageView ivhome = (ImageView) this.findViewById(R.id.imageView_home); 
     ivhome.setOnClickListener(new OnClickListener() { 

      public void onClick(View arg0) { 
       // TODO Auto-generated method stub 
       Intent intent = new Intent(Maps.this, GridViewContainer.class); 
       startActivity(intent); 
       finish(); 
      } 
     }); 
    } 

    @Override 
    protected boolean isRouteDisplayed() { 
     return false; 
    } 

    class MapOverlay extends Overlay { 

     private GeoPoint pointToDraw; 

     public void setPointToDraw(GeoPoint point) { 
      pointToDraw = point; 
     } 

     public GeoPoint getPointToDraw() { 
      return pointToDraw; 
     } 

     @Override 
     public boolean draw(Canvas canvas, MapView mapView, boolean shadow, 
       long when) { 
      super.draw(canvas, mapView, shadow); 
      Point screenPts = new Point(); 
      mapView.getProjection().toPixels(pointToDraw, screenPts); 
      Bitmap bmp = BitmapFactory.decodeResource(getResources(), 
       R.drawable.select_map); 
      canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 24, null); 
      return true; 
     } 
    } 
} 

main.xml:

<?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@android:color/black" 
     android:orientation="vertical" > 

     <com.google.android.maps.MapView 
      android:id="@+id/map_container" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:apiKey="yor api key" 
      android:clickable="true" 
      android:focusable="true" /> 

    </LinearLayout> 

и определить следующее разрешение в манифесте:

<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
1
public static Location getBestLocation(Context ctxt) { 
    Location gpslocation = getLocationByProvider(
     LocationManager.GPS_PROVIDER, ctxt); 
    Location networkLocation = getLocationByProvider(
     LocationManager.NETWORK_PROVIDER, ctxt); 
    Location fetchedlocation = null; 
    // if we have only one location available, the choice is easy 
    if (gpslocation != null) { 
     Log.i("New Location Receiver", "GPS Location available."); 
     fetchedlocation = gpslocation; 
    } else { 
     Log.i("New Location Receiver", 
      "No GPS Location available. Fetching Network location lat=" 
       + networkLocation.getLatitude() + " lon =" 
       + networkLocation.getLongitude()); 
     fetchedlocation = networkLocation; 
    } 
    return fetchedlocation; 
} 

/** 
* get the last known location from a specific provider (network/gps) 
*/ 
private static Location getLocationByProvider(String provider, Context ctxt) { 
    Location location = null; 
    // if (!isProviderSupported(provider)) { 
    // return null; 
    // } 
    LocationManager locationManager = (LocationManager) ctxt 
      .getSystemService(Context.LOCATION_SERVICE); 
    try { 
     if (locationManager.isProviderEnabled(provider)) { 
      location = locationManager.getLastKnownLocation(provider); 
     } 
    } catch (IllegalArgumentException e) { 
     Log.i("New Location Receiver", "Cannot access Provider " + provider); 
    } 
    return location; 
} 
1

Простой и лучший способ для GeoLocation.

LocationManager lm = null; 
boolean network_enabled; 


if (lm == null) 
       lm = (LocationManager) Kikit.this.getSystemService(Context.LOCATION_SERVICE); 

      network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

      dialog = ProgressDialog.show(Kikit.this, "", "Fetching location...", true); 


      final Handler handler = new Handler(); 
      timer = new Timer(); 
      TimerTask doAsynchronousTask = new TimerTask() { 

       @Override 
       public void run() { 
        handler.post(new Runnable() { 

         @Override 
         public void run() 
         { 

          Log.e("counter value","value "+counter); 

          if(counter<=8) 
          { 
           try 
           { 
            counter++; 


            if (network_enabled) { 

             lm = (LocationManager) Kikit.this.getSystemService(Context.LOCATION_SERVICE); 

             Log.e("in network_enabled..","in network_enabled"); 

             // Define a listener that responds to location updates 
             LocationListener locationListener = new LocationListener() 
             { 


              public void onLocationChanged(Location location) 
              { 
               if(attempt == false) 

               { 
                attempt = true; 
                Log.e("in location listener..","in location listener.."); 
                longi = location.getLongitude(); 
                lati = location.getLatitude(); 
                Data.longi = "" + longi; 
                Data.lati = "" + lati; 


                Log.e("longitude : ",""+longi); 
                Log.e("latitude : ",""+lati); 



                if(faceboo_name.equals("")) 
                { 
                 if(dialog!=null){ 
                 dialog.cancel();} 
                 timer.cancel(); 
                 timer.purge(); 
                 Data.homepage_resume = true; 
                 lm = null; 
                 Intent intent = new Intent();        
                 intent.setClass(Kikit.this,MainActivity.class); 

                 startActivity(intent);  
                 finish(); 
                } 
                else 
                {   

                 isInternetPresent = cd.isConnectingToInternet(); 

                 if (isInternetPresent) 
                 { 
                  if(dialog!=null) 
                   dialog.cancel(); 

                  Showdata(); 
                 } 
                 else 
                 { 
                  error_view.setText(Data.internet_error_msg); 
                  error_view.setVisibility(0); 
                  error_gone(); 
                 } 

                } 
               } 

              } 

              public void onStatusChanged(String provider, int status, 
                Bundle extras) { 
              } 

              public void onProviderEnabled(String provider) { 
               //Toast.makeText(getApplicationContext(), "Location enabled", Toast.LENGTH_LONG).show(); 

              } 

              public void onProviderDisabled(String provider) { 


              } 
             }; 



             // Register the listener with the Location Manager to receive 
             // location updates 
             lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 100000, 10,locationListener); 

            } else{ 
             //Toast.makeText(getApplicationContext(), "No Internet Connection.", 2000).show(); 
             buildAlertMessageNoGps(); 

            } 



           } catch (Exception e) { 
            // TODO 
            // Auto-generated 
            // catch 
            // block 
           } 
          } 
          else 
          { 

           timer.purge(); 
           timer.cancel(); 

           if(attempt == false) 
           { 
            attempt = true; 

            String locationProvider = LocationManager.NETWORK_PROVIDER; 
            // Or use LocationManager.GPS_PROVIDER 

            try { 
             Location lastKnownLocation = lm.getLastKnownLocation(locationProvider); 

             longi = lastKnownLocation.getLongitude(); 
             lati = lastKnownLocation.getLatitude(); 
             Data.longi = "" + longi; 
             Data.lati = "" + lati; 
            } catch (Exception e) { 
             // TODO Auto-generated catch block 
             e.printStackTrace(); 
             Log.i("exception in loc fetch", e.toString()); 
            } 

            Log.e("longitude of last known location : ",""+longi); 
            Log.e("latitude of last known location : ",""+lati); 

            if(Data.fb_access_token == "") 
            { 

             if(dialog!=null){ 
              dialog.cancel();} 
             timer.cancel(); 
             timer.purge(); 
             Data.homepage_resume = true; 
             Intent intent = new Intent();        
             intent.setClass(Kikit.this,MainActivity.class); 

             startActivity(intent); 
             finish(); 
            } 
            else 
            {   

             isInternetPresent = cd.isConnectingToInternet(); 

             if (isInternetPresent) 
             { 
              if(dialog!=null){ 
               dialog.cancel();}   
              Showdata(); 
             } 
             else 
             { 
              error_view.setText(Data.internet_error_msg); 
              error_view.setVisibility(0); 
              error_gone(); 
             } 

            } 

           } 
          } 
         } 
        }); 
       } 
      }; 
      timer.schedule(doAsynchronousTask, 0, 2000); 


private void buildAlertMessageNoGps() { 
     final AlertDialog.Builder builder = new AlertDialog.Builder(this); 

     builder.setMessage("Your WiFi & mobile network location is disabled , do you want to enable it?") 
     .setCancelable(false) 
     .setPositiveButton("Yes", new DialogInterface.OnClickListener() { 


      public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) 
      { 
       startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)); 
       setting_page = true; 
      } 
     }) 
     .setNegativeButton("No", new DialogInterface.OnClickListener() { 
      public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { 
       dialog.cancel(); 
       finish(); 
      } 
     }); 
     final AlertDialog alert = builder.create(); 
     alert.show(); 
    } 
4

Рекомендуемый способ сделать это состоит в использовании LocationClient:

Во-первых, определить значения интервала обновления местоположения. Отрегулируйте это для ваших нужд.

private static final int MILLISECONDS_PER_SECOND = 1000; 
private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS; 
private static final int FASTEST_INTERVAL_IN_SECONDS = 1; 
private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS; 

иметь свой Activity реализации GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener и LocationListener.

public class LocationActivity extends Activity implements 
GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {} 

Затем создать LocationClient в onCreate() методе вашего Activity:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    mLocationClient = new LocationClient(this, this, this); 

    mLocationRequest = LocationRequest.create(); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    mLocationRequest.setInterval(UPDATE_INTERVAL); 
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 
} 

добавить необходимые методы для вашего Activity; onConnected() - это метод, который вызывается при подключении LocationClient. onLocationChanged() - это место, где вы найдете самое современное местоположение.

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    Log.w(TAG, "Location client connection failed"); 
} 

@Override 
public void onConnected(Bundle dataBundle) { 
    Log.d(TAG, "Location client connected"); 
    mLocationClient.requestLocationUpdates(mLocationRequest, this); 
} 

@Override 
public void onDisconnected() { 
    Log.d(TAG, "Location client disconnected"); 
} 

@Override 
public void onLocationChanged(Location location) { 
    if (location != null) { 
     Log.d(TAG, "Updated Location: " + Double.toString(location.getLatitude()) + "," + Double.toString(location.getLongitude())); 
    } else { 
     Log.d(TAG, "Updated location NULL"); 
    } 
}  

Не забудьте подключить/отключить LocationClient так это только с помощью дополнительной батареи, когда это абсолютно необходимо, и поэтому GPS не работает на неопределенный срок. Для получения данных от него необходимо подключить LocationClient.

public void onResume() { 
    super.onResume(); 
    mLocationClient.connect(); 
} 

public void onStop() { 
    if (mLocationClient.isConnected()) { 
     mLocationClient.removeLocationUpdates(this); 
    } 
    mLocationClient.disconnect(); 
    super.onStop(); 
} 

Получить местонахождение пользователя. Сначала попробуйте использовать LocationClient; если это не удается, вернитесь к LocationManager.

public Location getLocation() { 
    if (mLocationClient != null && mLocationClient.isConnected()) { 
     return mLocationClient.getLastLocation(); 
    } else { 
     LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
     if (locationManager != null) { 
      Location lastKnownLocationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
      if (lastKnownLocationGPS != null) { 
       return lastKnownLocationGPS; 
      } else { 
       return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
      } 
     } else { 
      return null; 
     } 
    } 
} 
+1

не может решить locationclient – 2015-11-29 13:02:46

2

Хотя ответ уже указан здесь. Я просто хотел поделиться этим с миром, чтобы найти такой сценарий.

Мое требование состояло в том, что мне нужно было получить текущее местоположение пользователя в пределах от 30 до 35 секунд при макс, поэтому вот решение, которое я сделал после Nirav Ranpara's Answer.

1. Я сделал MyLocationManager.java класс, который обрабатывает все GPS и сети материал

import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 

import com.app.callbacks.OnLocationDetectectionListener; 

import android.app.AlertDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.provider.Settings; 
import android.util.Log; 
import android.widget.Toast; 

public class MyLocationManager { 
    /** The minimum distance to GPS change Updates in meters **/ 
    private final long MIN_DISTANCE_CHANGE_FOR_UPDATES_FOR_GPS = 2; // 2 
                    // meters 
    /** The minimum time between GPS updates in milliseconds **/ 
    private final long MIN_TIME_BW_UPDATES_OF_GPS = 1000 * 5 * 1; // 5 
                    // seconds 

    /** The minimum distance to NETWORK change Updates in meters **/ 
    private final long MIN_DISTANCE_CHANGE_FOR_UPDATES_FOR_NETWORK = 5; // 5 
                     // meters 
    /** The minimum time between NETWORK updates in milliseconds **/ 
    private final long MIN_TIME_BW_UPDATES_OF_NETWORK = 1000 * 10 * 1; // 10 
                     // seconds 

    /** 
    * Lets just say i don't trust the first location that the is found. This is 
    * to avoid that 
    **/ 

    private int NetworkLocationCount = 0, GPSLocationCount = 0; 
    private boolean isGPSEnabled; 
    private boolean isNetworkEnabled; 
    /** 
    * Don't do anything if location is being updated by Network or by GPS 
    */ 
    private boolean isLocationManagerBusy; 
    private LocationManager locationManager; 
    private Location currentLocation; 
    private Context mContext; 
    private OnLocationDetectectionListener mListener; 

    public MyLocationManager(Context mContext, 
      OnLocationDetectectionListener mListener) { 
     this.mContext = mContext; 
     this.mListener = mListener; 
    } 

    /** 
    * Start the location manager to find my location 
    */ 
    public void startLocating() { 
     try { 
      locationManager = (LocationManager) mContext 
        .getSystemService(Context.LOCATION_SERVICE); 

      // Getting GPS status 
      isGPSEnabled = locationManager 
        .isProviderEnabled(LocationManager.GPS_PROVIDER); 

      // Getting network status 
      isNetworkEnabled = locationManager 
        .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

      if (!isGPSEnabled && !isNetworkEnabled) { 
       // No network provider is enabled 
       showSettingsAlertDialog(); 
      } else { 
       // If GPS enabled, get latitude/longitude using GPS Services 
       if (isGPSEnabled) { 
        locationManager.requestLocationUpdates(
          LocationManager.GPS_PROVIDER, 
          MIN_TIME_BW_UPDATES_OF_GPS, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES_FOR_GPS, 
          gpsLocationListener); 

       } 
       if (isNetworkEnabled) { 
        locationManager.requestLocationUpdates(
          LocationManager.NETWORK_PROVIDER, 
          MIN_TIME_BW_UPDATES_OF_NETWORK, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES_FOR_NETWORK, 
          networkLocationListener); 

       } 
      } 
      /** 
      * My 30 seconds plan to get myself a location 
      */ 
      ScheduledExecutorService se = Executors 
        .newSingleThreadScheduledExecutor(); 
      se.schedule(new Runnable() { 

       @Override 
       public void run() { 
        if (currentLocation == null) { 
         if (isGPSEnabled) { 
          currentLocation = locationManager 
            .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
         } else if (isNetworkEnabled) { 
          currentLocation = locationManager 
            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

         } 
         if (currentLocation != null && mListener != null) { 
          locationManager.removeUpdates(gpsLocationListener); 
          locationManager 
            .removeUpdates(networkLocationListener); 
          mListener.onLocationDetected(currentLocation); 
         } 
        } 
       } 
      }, 30, TimeUnit.SECONDS); 

     } catch (Exception e) { 
      Log.e("Error Fetching Location", e.getMessage()); 
      Toast.makeText(mContext, 
        "Error Fetching Location" + e.getMessage(), 
        Toast.LENGTH_SHORT).show(); 
     } 
    } 

    /** 
    * Handle GPS location listener callbacks 
    */ 
    private LocationListener gpsLocationListener = new LocationListener() { 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onProviderEnabled(String provider) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onProviderDisabled(String provider) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onLocationChanged(Location location) { 

      if (GPSLocationCount != 0 && !isLocationManagerBusy) { 
       Log.d("GPS Enabled", "GPS Enabled"); 
       isLocationManagerBusy = true; 
       currentLocation = location; 
       locationManager.removeUpdates(gpsLocationListener); 
       locationManager.removeUpdates(networkLocationListener); 
       isLocationManagerBusy = false; 
       if (currentLocation != null && mListener != null) { 
        mListener.onLocationDetected(currentLocation); 
       } 
      } 
      GPSLocationCount++; 
     } 
    }; 
    /** 
    * Handle Network location listener callbacks 
    */ 
    private LocationListener networkLocationListener = new LocationListener() { 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onProviderEnabled(String provider) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onProviderDisabled(String provider) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onLocationChanged(Location location) { 
      if (NetworkLocationCount != 0 && !isLocationManagerBusy) { 
       Log.d("Network", "Network"); 
       isLocationManagerBusy = true; 
       currentLocation = location; 
       locationManager.removeUpdates(gpsLocationListener); 
       locationManager.removeUpdates(networkLocationListener); 
       isLocationManagerBusy = false; 
       if (currentLocation != null && mListener != null) { 
        mListener.onLocationDetected(currentLocation); 
       } 
      } 
      NetworkLocationCount++; 
     } 
    }; 

    /** 
    * Function to show settings alert dialog. On pressing the Settings button 
    * it will launch Settings Options. 
    * */ 
    public void showSettingsAlertDialog() { 
     AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext); 

     // Setting Dialog Title 
     alertDialog.setTitle("GPS is settings"); 

     // Setting Dialog Message 
     alertDialog 
       .setMessage("GPS is not enabled. Do you want to go to settings menu?"); 

     // On pressing the Settings button. 
     alertDialog.setPositiveButton("Settings", 
       new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         Intent intent = new Intent(
           Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
         mContext.startActivity(intent); 
        } 
       }); 

     // On pressing the cancel button 
     alertDialog.setNegativeButton("Cancel", 
       new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         dialog.cancel(); 
        } 
       }); 

     // Showing Alert Message 
     alertDialog.show(); 
    } 
} 

2. Я сделал интерфейс (обратный вызов) OnLocationDetectectionListener.java для того, чтобы передавать результаты обратно вызывающему фрагменту или активности

import android.location.Location; 

public interface OnLocationDetectectionListener { 
    public void onLocationDetected(Location mLocation); 
} 

3. Тогда я сделал MainAppActivty.java активности, которая реализует интерфейс OnLocationDetectectionListener и вот как я получаю мое местоположение в нем

public class MainAppActivty extends Activity implements 
     OnLocationDetectectionListener { 

    private Location currentLocation; 
    private MyLocationManager mLocationManager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     setContentView(R.layout.activity_home); 
     super.onCreate(savedInstanceState); 
      mLocationManager = new MyLocationManager(this, this); 
      mLocationManager.startLocating(); 
    } 

    @Override 
    public void onLocationDetected(Location mLocation) { 
     //Your new Location is received here 
     currentLocation = mLocation; 
    } 

4. Добавьте следующие разрешения для вашего файла манифеста

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

Надеется, что это полезно для других :)

2

EDIT: обновление с последней Location Service API из Google Play библиотеки служб (июль 2014)

Я бы порекомендовал вам использовать новый Location Service API, доступный из Google Play библиотеки Services, которая обеспечивает более мощный, высокоуровневую структуру, которая автоматизирует такие задачи, как выбор поставщика услуг и управление питанием. Согласно официальной документации: «...API Location упрощает создание приложений, ориентированных на местоположение, без необходимости фокусироваться на деталях базовой технологии определения местоположения. Кроме того, они позволяют свести к минимуму потребления энергии, используя все возможности аппаратного устройства «

Для получения дополнительной информации посетите:. Making Your App Location-Aware

Чтобы увидеть полный пример с использованием новейшего Места службы API визита: Android LocationClient class is deprecated but used in documentation

1

Немного поздно, но в такой ситуации я бы воспользовался API Карт Google и отметил близлежащие местоположения, используя lat и long API карт Google. Плюс пользовательский интерфейс лучше, если вы можете показать свое местоположение на карте. Не нужно беспокоиться об обновлении местоположения пользователя или обхода с помощью android api. Пусть карты Google обрабатывают внутренние элементы для вас.

@emmby, возможно, принял решение в своем приложении, но для дальнейшего использования взглядом на API карт Google для конкретных местоположений я рекомендую другим разработчикам.

Edit: Ссылка для отображения user location in google maps

5

я написал подробный учебник, охватывающий current location здесь demonuts.com .Вы можете найти больше здесь описание, а также вы можете скачать весь демонстрационный исходный код для лучшего понимания.

Есть уже много ответов там, но я хочу, чтобы показать последний способ получить местоположение с помощью Google API, так что новые программисты могут использовать новый метод:

Прежде всего, сделать это в Gradle файла

compile 'com.google.android.gms:play-services:8.4.0' 

затем реализовать необходимые интерфейсы

public class MainActivity extends BaseActivitiy implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener 

объявить экземпляры

private GoogleApiClient mGoogleApiClient; 
    private Location mLocation; 
    private LocationManager locationManager; 
    private LocationRequest mLocationRequest; 

положить это в onCreate()

mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
     locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 

наконец, переопределить необходимые методы

@Override 
    public void onConnected(Bundle bundle) { 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return; 
     } 
     mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     if(mLocation == null){ 
      startLocationUpdates(); 
     } 
     if (mLocation != null) { 
      double latitude = mLocation.getLatitude(); 
      double longitude = mLocation.getLongitude(); 
     } else { 
      // Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show(); 
     } 
    } 

    protected void startLocationUpdates() { 
     // Create the location request 
     mLocationRequest = LocationRequest.create() 
       .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
       .setInterval(UPDATE_INTERVAL) 
       .setFastestInterval(FASTEST_INTERVAL); 
     // Request location updates 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return; 
     } 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, 
       mLocationRequest, this); 
     Log.d("reque", "--->>>>"); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.i(TAG, "Connection Suspended"); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode()); 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     if (mGoogleApiClient.isConnected()) { 
      mGoogleApiClient.disconnect(); 
     } 
    } 
    @Override 
    public void onLocationChanged(Location location) { 

    } 

Не забудьте начать GPS в устройстве перед запуском приложения.

+0

Использование API? Так что это сервис с ограничением скорости. – user3304007

0

Используя FusedLocationProviderApi, который является последним API и лучшим среди доступных возможностей для размещения на Android. добавить это в build.gradle файле

dependencies { 
    compile 'com.google.android.gms:play-services:6.5.87' 
} 

вы можете получить полный исходный код этого URL http://javapapers.com/android/android-location-fused-provider/

0

Вот что я делаю:

  1. Прежде всего я проверяю ли NETWORK или GPS провайдеры включены. Некоторые могут быть отключены на устройстве, некоторые могут быть отключены в манифесте приложения. Если какой-либо провайдер включен, я получаю кэшированное последнее место для этого провайдера и начинаю прослушивание обновления местоположения для этого провайдера.
  2. Существует способ определения того, является ли местоположение лучше, чем последнее полученное местоположение, как указано в ссылке: - https://developer.android.com/guide/topics/location/strategies.html#BestEstimate
  3. Если я получаю обновление от приемника местоположения, я проверяю, лучше ли это местоположение, чем ранее полученное местоположение. и Если это лучше, чем заменить это место на предыдущее лучшее место (mFinalLocation).
  4. Существует также обработчик (таймер) в течение двух минут, что в конечном итоге прекращает обслуживание и в методе обслуживания onDestroy() прекращает прослушивание обновлений местоположения для каждого из провайдеров.

Ниже приведен код обслуживания. Вы можете запустить его на основе частоты обновления местоположения, в которой вы нуждаетесь.

import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.IBinder; 
import android.os.Message; 
import android.support.annotation.Nullable; 
import android.util.Log; 


public class RecordLocationService extends Service { 

    private final String TAG = RecordLocationService.class.getSimpleName(); 

    private final int TWO_MINUTES = 1000 * 60 * 2; 

    private LocationManager mLocationManager; 

    private MyLocationListener mLocationListeners[] = new MyLocationListener[]{ 
      new MyLocationListener(LocationManager.NETWORK_PROVIDER), 
      new MyLocationListener(LocationManager.GPS_PROVIDER) 
    }; 

    private Location mFinalLocation; 

    private class MyLocationListener implements LocationListener { 
     private String mProvider; 

     public MyLocationListener(String provider) { 
      Log.d(TAG, "LocationListener : " + provider); 
      mProvider = provider; 
     } 

     public String getProvider() { 
      return mProvider; 
     } 

     @Override 
     public void onLocationChanged(Location location) { 
      Log.d(TAG, "onLocationChanged : " + location); 

      if (isBetterLocation(location, mFinalLocation)) { 
       Log.d(TAG, "Setting current Final Location to recent most Location for Provider : " + location.getProvider()); 
       Log.d(TAG, "Setting current Final Location to : " + location); 
       mFinalLocation = location; 
      } else { 
       Log.d(TAG, "Keeping current Final Location to previous Final Location"); 
      } 

     } 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      Log.d(TAG, "onStatusChanged provider " + provider); 
     } 

     @Override 
     public void onProviderEnabled(String provider) { 
      Log.d(TAG, "onProviderEnabled provider " + provider); 
     } 

     @Override 
     public void onProviderDisabled(String provider) { 
      Log.d(TAG, "onProviderDisabled provider " + provider); 
     } 
    } 

    private Handler mStopServiceHandler = new Handler() { 

     @Override 
     public void handleMessage(Message msg) { 
      switch (msg.what) { 
       case 1: { 
        stopSelf(); 
       } 
       break; 
      } 
     } 
    }; 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     super.onStartCommand(intent, flags, startId); 
     Log.d(TAG, "onStartCommand"); 
     return START_STICKY; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Log.d(TAG, "onCreate"); 
     requestLocation(); 
     mStopServiceHandler.sendEmptyMessageDelayed(1, TWO_MINUTES); 
    } 

    private void requestLocation() { 
     // Acquire a reference to the system Location Manager 
     if (mLocationManager == null) { 
      mLocationManager = (LocationManager) this.getApplicationContext().getSystemService(Context.LOCATION_SERVICE); 
     } 

     try { 
      if (mLocationManager.getAllProviders().contains(LocationManager.NETWORK_PROVIDER) && mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { 
       Log.d(TAG, "Fetching Cached Location for Provider : " + LocationManager.NETWORK_PROVIDER); 
       Location cachedNetworkLocation = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

       if (cachedNetworkLocation != null) { 
        Log.d(TAG, "Setting Final Location to Cached Location for Provider : " + LocationManager.NETWORK_PROVIDER); 
        Log.d(TAG, "Setting Final Location to : " + cachedNetworkLocation); 
        mFinalLocation = cachedNetworkLocation; 
       } else { 
        Log.d(TAG, "Cached Location for Provider : " + LocationManager.NETWORK_PROVIDER + " is NULL"); 
       } 

       Log.d(TAG, "Requesting Location Update for Provider : " + LocationManager.NETWORK_PROVIDER); 
       mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListeners[0]); 
      } 

     } catch (SecurityException se) { 
      Log.e(TAG, se.getMessage(), se); 
     } catch (IllegalArgumentException iae) { 
      Log.e(TAG, iae.getMessage(), iae); 
     } 

     try { 
      if (mLocationManager.getAllProviders().contains(LocationManager.GPS_PROVIDER) && mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 
       Log.d(TAG, "Fetching Cached Location for Provider : " + LocationManager.GPS_PROVIDER); 
       Location cachedGPSLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 

       if (cachedGPSLocation != null) { 
        if (isBetterLocation(cachedGPSLocation, mFinalLocation)) { 
         Log.d(TAG, "Setting Final Location to Cached Location for Provider : " + LocationManager.GPS_PROVIDER); 
         Log.d(TAG, "Setting Final Location to : " + cachedGPSLocation); 
         mFinalLocation = cachedGPSLocation; 
        } 
       } else { 
        Log.d(TAG, "Cached Location for Provider : " + LocationManager.GPS_PROVIDER + " is NULL"); 
       } 

       Log.d(TAG, "Requesting Location Update for Provider : " + LocationManager.GPS_PROVIDER); 
       mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListeners[1]); 
      } 

     } catch (SecurityException se) { 
      Log.e(TAG, se.getMessage(), se); 
     } catch (IllegalArgumentException iae) { 
      Log.e(TAG, iae.getMessage(), iae); 
     } 


    } 

    /** 
    * Determines whether one Location reading is better than the current Location fix 
    * 
    * @param location   The new Location that you want to evaluate 
    * @param currentBestLocation The current Location fix, to which you want to compare the new one 
    */ 
    protected boolean isBetterLocation(Location location, Location currentBestLocation) { 
     if (currentBestLocation == null) { 
      // A new location is always better than no location 
      return true; 
     } 

     // Check whether the new location fix is newer or older 
     long timeDelta = location.getTime() - currentBestLocation.getTime(); 
     boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; 
     boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; 
     boolean isNewer = timeDelta > 0; 

     // If it's been more than two minutes since the current location, use the new location 
     // because the user has likely moved 
     if (isSignificantlyNewer) { 
      return true; 
      // If the new location is more than two minutes older, it must be worse 
     } else if (isSignificantlyOlder) { 
      return false; 
     } 

     // Check whether the new location fix is more or less accurate 
     int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); 
     boolean isLessAccurate = accuracyDelta > 0; 
     boolean isMoreAccurate = accuracyDelta < 0; 
     boolean isSignificantlyLessAccurate = accuracyDelta > 200; 

     // Check if the old and new location are from the same provider 
     boolean isFromSameProvider = isSameProvider(location.getProvider(), 
       currentBestLocation.getProvider()); 

     // Determine location quality using a combination of timeliness and accuracy 
     if (isMoreAccurate) { 
      return true; 
     } else if (isNewer && !isLessAccurate) { 
      return true; 
     } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 
      return true; 
     } 
     return false; 
    } 

    /** 
    * Checks whether two providers are the same 
    */ 
    private boolean isSameProvider(String provider1, String provider2) { 
     if (provider1 == null) { 
      return provider2 == null; 
     } 
     return provider1.equals(provider2); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d(TAG, "onDestroy"); 
     if (mLocationManager != null) { 
      for (int i = 0; i < mLocationListeners.length; i++) { 
       try { 
        Log.d(TAG, "Removing Location Update for Provider : " + mLocationListeners[i].getProvider()); 
        mLocationManager.removeUpdates(mLocationListeners[i]); 
       } catch (Exception ex) { 
        Log.e(TAG, "fail to remove location listeners, ignore", ex); 
       } 
      } 
     } 
    } 
} 
1

Это требует много вещей на месте, чтобы получить обновление местоположения в андроиде, требует много bolierplate кода.

Вы должны заботиться о

  • сервисов Google Play за доступностью Проверьте,
  • Обновление Google Play Service, если он старый или не доступен
  • Dialog Создание GoogleApiClient и его функции обратного вызова подключен, отключен и т.д.
  • Остановка и освобождение ресурсов на размещение обновлений
  • Справки по разрешению местоположения
  • Проверка Опред.местополож Вкл или Выкл
  • Получение lastknown расположение не так легко либо
  • Запасной до последнего известного местоположения, если не получить местоположение после определенного периода

я создал Android-EasyLocation (small android library), который будет заботиться все это и вы можете сосредоточиться на бизнес-логике.

Все, что вам нужно продлить EasyLocationActivity и это

requestSingleLocationFix(easyLocationRequest); 

или

requestLocationUpdates(easyLocationRequest); 

заказ образец приложения и шаги, необходимые здесь https://github.com/akhgupta/Android-EasyLocation

-1

Прежде чем ответить, я просто хочу будьте откровенны в связи с тем, что я связан с Neura. Теперь на ваш вопрос. Итак, вместо того, чтобы тратить время на кодирование, чтобы получить свое местоположение пользователя, вы можете использовать наш SDK. Для интеграции требуется менее 30 минут. Neura предоставляет вам местоположение/активность вашего пользователя, и вы можете настроить приложение для выполнения определенных задач после получения данных. Вот несколько причин использовать Neura над другими API-интерфейсами для определения активности:

  1. Не нужно указывать тонны строк, чтобы понять вашего пользователя.
  2. Дает точные результаты.
  3. Потребляет менее 1% заряда аккумулятора.
+1

Что это за ерунда? «Потребляет менее 1% вашей батареи». - Как это даже аргумент? 1% за сколько? –

0

Недавно реорганизованный для определения местоположения кода, изучения некоторых хороших идей и, наконец, достижения относительно совершенной библиотеки и демонстрации.

//request all valid provider(network/gps) 
private boolean requestAllProviderUpdates() { 
    checkRuntimeEnvironment(); 
    checkPermission(); 

    if (isRequesting) { 
     EasyLog.d("Request location update is busy"); 
     return false; 
    } 


    long minTime = getCheckTimeInterval(); 
    float minDistance = getCheckMinDistance(); 

    if (mMapLocationListeners == null) { 
     mMapLocationListeners = new HashMap<>(); 
    } 

    mValidProviders = getValidProviders(); 
    if (mValidProviders == null || mValidProviders.isEmpty()) { 
     throw new IllegalArgumentException("Not available provider."); 
    } 

    for (String provider : mValidProviders) { 
     LocationListener locationListener = new LocationListener() { 
      @Override 
      public void onLocationChanged(Location location) { 
       if (location == null) { 
        EasyLog.e("LocationListener callback location is null."); 
        return; 
       } 
       printf(location); 
       mLastProviderTimestamp = location.getTime(); 

       if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) { 
        finishResult(location); 
       } else { 
        doLocationResult(location); 
       } 

       removeProvider(location.getProvider()); 
       if (isEmptyValidProviders()) { 
        requestTimeoutMsgInit(); 
        removeUpdates(); 
       } 
      } 

      @Override 
      public void onStatusChanged(String provider, int status, Bundle extras) { 
      } 

      @Override 
      public void onProviderEnabled(String provider) { 
      } 

      @Override 
      public void onProviderDisabled(String provider) { 
      } 
     }; 
     getLocationManager().requestLocationUpdates(provider, minTime, minDistance, locationListener); 
     mMapLocationListeners.put(provider, locationListener); 
     EasyLog.d("Location request %s provider update.", provider); 
    } 
    isRequesting = true; 
    return true; 
} 

//remove request update 
public void removeUpdates() { 
    checkRuntimeEnvironment(); 

    LocationManager locationManager = getLocationManager(); 
    if (mMapLocationListeners != null) { 
     Set<String> keys = mMapLocationListeners.keySet(); 
     for (String key : keys) { 
      LocationListener locationListener = mMapLocationListeners.get(key); 
      if (locationListener != null) { 
       locationManager.removeUpdates(locationListener); 
       EasyLog.d("Remove location update, provider is " + key); 
      } 
     } 
     mMapLocationListeners.clear(); 
     isRequesting = false; 
    } 
} 

//Compared with the last successful position, to determine whether you need to filter 
private boolean isNeedFilter(Location location) { 
    checkLocation(location); 

    if (mLastLocation != null) { 
     float distance = location.distanceTo(mLastLocation); 
     if (distance < getCheckMinDistance()) { 
      return true; 
     } 
     if (location.getAccuracy() >= mLastLocation.getAccuracy() 
       && distance < location.getAccuracy()) { 
      return true; 
     } 
     if (location.getTime() <= mLastProviderTimestamp) { 
      return true; 
     } 
    } 
    return false; 
} 

private void doLocationResult(Location location) { 
    checkLocation(location); 

    if (isNeedFilter(location)) { 
     EasyLog.d("location need to filtered out, timestamp is " + location.getTime()); 
     finishResult(mLastLocation); 
    } else { 
     finishResult(location); 
    } 
} 

//Return to the finished position 
private void finishResult(Location location) { 
    checkLocation(location); 

    double latitude = location.getLatitude(); 
    double longitude = location.getLongitude(); 
    float accuracy = location.getAccuracy(); 
    long time = location.getTime(); 
    String provider = location.getProvider(); 

    if (mLocationResultListeners != null && !mLocationResultListeners.isEmpty()) { 
     String format = "Location result:<%f, %f> Accuracy:%f Time:%d Provider:%s"; 
     EasyLog.i(String.format(format, latitude, longitude, accuracy, time, provider)); 

     mLastLocation = location; 
     synchronized (this) { 
      Iterator<LocationResultListener> iterator = mLocationResultListeners.iterator(); 
      while (iterator.hasNext()) { 
       LocationResultListener listener = iterator.next(); 
       if (listener != null) { 
        listener.onResult(location); 
       } 
       iterator.remove(); 
      } 
     } 
    } 
} 

Полный код: https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java

* Каждый запрос, чтобы завершить место, то лучше removeUpdates, в противном случае в строке состояния телефона всегда будет отображаться значок позиционирования.

Смежные вопросы