2009-10-03 3 views
577

Мне нужно получить мое текущее местоположение, используя GPS программно. Как я могу это достичь?Как получить текущее местоположение GPS программно в Android?

+4

Я Написал мой пример кода [здесь] (http://stackoverflow.com/questions/3145089/what - это самый простой и самый надежный способ для получения-пользователя-current-location-in-an/3145655 # 3145655) – Fedor

+4

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

+0

Вы можете использовать библиотеку [Android-SimpleLocation] (https://github.com/delight-im/Android-SimpleLocation) (лицензия Apache) для упрощения доступа к местоположению – caw

ответ

357

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

Полный исходный код примера находится в Get Current Location coordinates , City name - in Android.


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

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

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

    LocationManager locationManager = (LocationManager) 
    getSystemService(Context.LOCATION_SERVICE); 
    
  • Проверьте, включен ли 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) {} 
} 

+20

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

+9

@NiiLaryea, потому что я получаю Location, используя метод ** onLocationChanged() **, который дает каждый раз новое местоположение во время перемещения, , но если вы хотите всего один раз, вам нужно позвонить «** getLastKnownLocation() ** " – swiftBoy

+0

Если в адресах есть только один адрес, строка, начинающаяся с' cityName = ', завершится с ошибкой. Использование фигурных скоб зафиксирует его. – Carrotman42

108

Вот дополнительная информация другие ответы.

Поскольку Android имеет

GPS_PROVIDER and NETWORK_PROVIDER 

вы можете зарегистрироваться как и начать получать события из onLocationChanged(Location location) из двух одновременно. Все идет нормально. Теперь вопрос о том, нужны ли нам два результата, или мы должны взять лучшее. Как я знаю GPS_PROVIDER результаты имеют лучшую точность, чем NETWORK_PROVIDER.

Определим Location поле:

private Location currentBestLocation = null; 

Перед тем, как начать слушать Место изменения мы реализуем следующий метод. Этот метод возвращает последнее известное местоположение, между GPS и сетевым. Для этого метода лучше.

/** 
* @return the last know best location 
*/ 
private Location getLastBestLocation() { 
    Location locationGPS = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
    Location locationNet = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

    long GPSLocationTime = 0; 
    if (null != locationGPS) { GPSLocationTime = locationGPS.getTime(); } 

    long NetLocationTime = 0; 

    if (null != locationNet) { 
     NetLocationTime = locationNet.getTime(); 
    } 

    if (0 < GPSLocationTime - NetLocationTime) { 
     return locationGPS; 
    } 
    else { 
     return locationNet; 
    } 
} 

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

... 
static final int TWO_MINUTES = 1000 * 60 * 2; 
... 

добавить новый метод onLocationChanged:

@override 
public void onLocationChanged(Location location) { 

    makeUseOfNewLocation(location); 

    if(currentBestLocation == null){ 
     currentBestLocation = location; 
    } 

    .... 
} 


/** 
* This method modify the last know good location according to the arguments. 
* 
* @param location The possible new location. 
*/ 
void makeUseOfNewLocation(Location location) { 
    if (isBetterLocation(location, currentBestLocation)) { 
     currentBestLocation = location; 
    } 
} 

.... 

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

.... 
+0

Привет, Это хороший пример .. но не могли бы вы дать мне более полный пример? У меня возникли проблемы с его интеграцией в мой существующий код. Кроме того, я использую только GPS в качестве поставщика. – beerBear

+1

@quantumstates Я думаю, что он довольно полный. Просто создайте поле 'private Location currentBestLocation = null;' и добавьте 'makeUseOfNewLocation (location);' to onLocationChanged (..) method –

+0

Спасибо Maxim. У меня есть вопрос. Где вы используете метод getLastBestLocation? –

72

Вы можете найти место либо GPS_PROVIDER or NETWORK_PROVIDER.

Обзор location services в Android.

Вот один пример, который пытается найти местоположение с помощью GPS. Если ваш GPS недоступен, попробуйте использовать сеть для поиска местоположения.

GPSTracker.java

public class GPSTracker extends Service implements LocationListener { 

    private final Context mContext; 

    // Flag for GPS status 
    boolean isGPSEnabled = false; 

    // Flag for network status 
    boolean isNetworkEnabled = false; 

    // Flag for GPS status 
    boolean canGetLocation = false; 

    Location location; // Location 
    double latitude; // Latitude 
    double longitude; // Longitude 

    // The minimum distance to change Updates in meters 
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters 

    // The minimum time between updates in milliseconds 
    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute 

    // Declaring a Location Manager 
    protected LocationManager locationManager; 

    public GPSTracker(Context context) { 
     this.mContext = context; 
     getLocation(); 
    } 

    public Location getLocation() { 
     try { 
      locationManager = (LocationManager) mContext 
        .getSystemService(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 
      } else { 
       this.canGetLocation = true; 
       if (isNetworkEnabled) { 
        locationManager.requestLocationUpdates(
          LocationManager.NETWORK_PROVIDER, 
          MIN_TIME_BW_UPDATES, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        Log.d("Network", "Network"); 
        if (locationManager != null) { 
         location = locationManager 
           .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
         if (location != null) { 
          latitude = location.getLatitude(); 
          longitude = location.getLongitude(); 
         } 
        } 
       } 
       // If GPS enabled, get latitude/longitude using GPS Services 
       if (isGPSEnabled) { 
        if (location == null) { 
         locationManager.requestLocationUpdates(
           LocationManager.GPS_PROVIDER, 
           MIN_TIME_BW_UPDATES, 
           MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
         Log.d("GPS Enabled", "GPS Enabled"); 
         if (locationManager != null) { 
          location = locationManager 
            .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
          if (location != null) { 
           latitude = location.getLatitude(); 
           longitude = location.getLongitude(); 
          } 
         } 
        } 
       } 
      } 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return location; 
    } 


    /** 
    * Stop using GPS listener 
    * Calling this function will stop using GPS in your app. 
    * */ 
    public void stopUsingGPS(){ 
     if(locationManager != null){ 
      locationManager.removeUpdates(GPSTracker.this); 
     } 
    } 


    /** 
    * Function to get latitude 
    * */ 
    public double getLatitude(){ 
     if(location != null){ 
      latitude = location.getLatitude(); 
     } 

     // return latitude 
     return latitude; 
    } 


    /** 
    * Function to get longitude 
    * */ 
    public double getLongitude(){ 
     if(location != null){ 
      longitude = location.getLongitude(); 
     } 

     // return longitude 
     return longitude; 
    } 

    /** 
    * Function to check GPS/Wi-Fi enabled 
    * @return boolean 
    * */ 
    public boolean canGetLocation() { 
     return this.canGetLocation; 
    } 


    /** 
    * Function to show settings alert dialog. 
    * On pressing the Settings button it will launch Settings Options. 
    * */ 
    public void showSettingsAlert(){ 
     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() { 
      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() { 
      public void onClick(DialogInterface dialog, int which) { 
      dialog.cancel(); 
      } 
     }); 

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


    @Override 
    public void onLocationChanged(Location location) { 
    } 


    @Override 
    public void onProviderDisabled(String provider) { 
    } 


    @Override 
    public void onProviderEnabled(String provider) { 
    } 


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


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

активность -AndroidGPSTrackingActivity.java

public class AndroidGPSTrackingActivity extends Activity { 

    Button btnShowLocation; 

    // GPSTracker class 
    GPSTracker gps; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     btnShowLocation = (Button) findViewById(R.id.btnShowLocation); 

     // Show location button click event 
     btnShowLocation.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       // Create class object 
       gps = new GPSTracker(AndroidGPSTrackingActivity.this); 

       // Check if GPS enabled 
       if(gps.canGetLocation()) { 

        double latitude = gps.getLatitude(); 
        double longitude = gps.getLongitude(); 

        // \n is for new line 
        Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show(); 
       } else { 
        // Can't get location. 
        // GPS or network is not enabled. 
        // Ask user to enable GPS/network in settings. 
        gps.showSettingsAlert(); 
       } 
      } 
     }); 
    } 
} 

layout- main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <Button android:id="@+id/btnShowLocation" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Show Location" 
     android:layout_centerVertical="true" 
     android:layout_centerHorizontal="true"/> 
</RelativeLayout> 

AndroidManifest.xml

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

Я думаю, что в этом примере есть проблема, вы никогда похоже, использует приемник местоположения. Он всегда использует GetLastKnownLocation(), который может быть не последним. –

+12

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

+5

Почему вы создавали экземпляр службы, а не использовали метод startService() ???? – 2014-09-10 01:37:04

10
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 the 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(), 5000); 
     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); 
    } 
} 

Я надеюсь, что это поможет ...

+1

Не забудьте добавить следующую строку в ваш файл AndroidManifest: '' –

3

При создании новых проектов местоположения для Android вы должны использовать новые Google Play услуги определения местоположения. Он намного точнее и намного проще в использовании.

Я работаю над an open source GPS tracker project, GpsTracker, в течение нескольких лет. Недавно я обновил его для обработки периодических обновлений сотовых телефонов Android, iOS, Windows Phone и Java ME. Он полностью функциональный и делает то, что вам нужно, и имеет MIT License.

Проект Android в GpsTracker использует новые сервисы Google Play, а также два сервераных стека (ASP.NET и PHP), чтобы вы могли отслеживать эти телефоны.

+3

Проблема в том, что не все устройства имеют Службы Google Play, включая любой пользовательский ROM это не пиратство. Если вы собираетесь использовать его, получите резервную копию для LocationManager. –

5

Теперь, когда Google Play locations services здесь, я рекомендую, чтобы разработчики начали использовать новый поставщик плавного доступа. Вам будет проще использовать и более точно. Пожалуйста, просмотрите видео Google I/OBeyond the Blue Dot: New Features in Android Location двумя парнями, которые создали новый API сервисов местоположения Google Play.

Я работаю с API определения местоположения на нескольких мобильных платформах, и я думаю, что эти два парня сделали действительно революционным. Он избавился от огромного количества сложностей при использовании различных поставщиков. Stack Overflow усеяно вопросами о том, какой провайдер должен использовать, использовать последнее известное местоположение, как установить другие свойства в LocationManager и т. Д. Этот новый API, который они создали, удаляет большую часть этих неопределенностей и делает службы местоположения приятными использовать.

Я написал приложение для Android, которое периодически получает местоположение с помощью служб местоположения Google Play и отправляет его на веб-сервер, где он хранится в базе данных, и может быть просмотрен на Google Maps.Я написал как клиентское программное обеспечение (для Android, iOS, Windows Phone и Java ME), так и для серверного программного обеспечения (для ASP.NET и SQL Server или PHP и MySQL). Программное обеспечение написано на родном языке на каждой платформе и работает правильно в фоновом режиме на каждом. Наконец, программное обеспечение имеет MIT License. Вы можете найти Android-клиент здесь:

https://github.com/nickfox/GpsTracker/tree/master/phoneClients/android

32

Поскольку я не как некоторые из кода в других ответов, вот мое простое решение. Это решение предназначено для использования в Activity или Service для отслеживания местоположения. Он гарантирует, что он никогда не возвращает данные, которые слишком устарели, если вы явно не запрашиваете устаревшие данные. Его можно запустить либо в режиме обратного вызова, чтобы получать обновления по мере их получения, либо в режиме опроса для опроса самой последней информации.

Общий интерфейс LocationTracker. Позволяет нам иметь несколько типов трекер местоположения и вставьте подходящую в легко:

package com.gabesechan.android.reusable.location; 

import android.location.Location; 

public interface LocationTracker { 
    public interface LocationUpdateListener{ 
     public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime); 
    } 

    public void start(); 
    public void start(LocationUpdateListener update); 

    public void stop(); 

    public boolean hasLocation(); 

    public boolean hasPossiblyStaleLocation(); 

    public Location getLocation(); 

    public Location getPossiblyStaleLocation(); 

} 

ProviderLocationTracker- этот класс будет отслеживать местоположение любого GPS или сеть.

package com.gabesechan.android.reusable.location; 

import android.content.Context; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 

public class ProviderLocationTracker implements LocationListener, LocationTracker { 

    // The minimum distance to change Updates in meters 
    private static final long MIN_UPDATE_DISTANCE = 10; 

    // The minimum time between updates in milliseconds 
    private static final long MIN_UPDATE_TIME = 1000 * 60; 

    private LocationManager lm; 

    public enum ProviderType{ 
     NETWORK, 
     GPS 
    };  
    private String provider; 

    private Location lastLocation; 
    private long lastTime; 

    private boolean isRunning; 

    private LocationUpdateListener listener; 

    public ProviderLocationTracker(Context context, ProviderType type) { 
     lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); 
     if(type == ProviderType.NETWORK){ 
      provider = LocationManager.NETWORK_PROVIDER; 
     } 
     else{ 
      provider = LocationManager.GPS_PROVIDER; 
     } 
    } 

    public void start(){ 
     if(isRunning){ 
      //Already running, do nothing 
      return; 
     } 

     //The provider is on, so start getting updates. Update current location 
     isRunning = true; 
     lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this); 
     lastLocation = null; 
     lastTime = 0; 
     return; 
    } 

    public void start(LocationUpdateListener update) { 
     start(); 
     listener = update; 

    } 


    public void stop(){ 
     if(isRunning){ 
      lm.removeUpdates(this); 
      isRunning = false; 
      listener = null; 
     } 
    } 

    public boolean hasLocation(){ 
     if(lastLocation == null){ 
      return false; 
     } 
     if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){ 
      return false; //stale 
     } 
     return true; 
    } 

    public boolean hasPossiblyStaleLocation(){ 
     if(lastLocation != null){ 
      return true; 
     } 
     return lm.getLastKnownLocation(provider)!= null; 
    } 

    public Location getLocation(){ 
     if(lastLocation == null){ 
      return null; 
     } 
     if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){ 
      return null; //stale 
     } 
     return lastLocation; 
    } 

    public Location getPossiblyStaleLocation(){ 
     if(lastLocation != null){ 
      return lastLocation; 
     } 
     return lm.getLastKnownLocation(provider); 
    } 

    public void onLocationChanged(Location newLoc) { 
     long now = System.currentTimeMillis(); 
     if(listener != null){ 
      listener.onUpdate(lastLocation, lastTime, newLoc, now); 
     } 
     lastLocation = newLoc; 
     lastTime = now; 
    } 

    public void onProviderDisabled(String arg0) { 

    } 

    public void onProviderEnabled(String arg0) { 

    } 

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

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

package com.gabesechan.android.reusable.location; 

import android.content.Context; 
import android.location.Location; 
import android.location.LocationManager; 

public class FallbackLocationTracker implements LocationTracker, LocationTracker.LocationUpdateListener { 


    private boolean isRunning; 

    private ProviderLocationTracker gps; 
    private ProviderLocationTracker net; 

    private LocationUpdateListener listener; 

    Location lastLoc; 
    long lastTime; 

    public FallbackLocationTracker(Context context) { 
     gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS); 
     net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK); 
    } 

    public void start(){ 
     if(isRunning){ 
      //Already running, do nothing 
      return; 
     } 

     //Start both 
     gps.start(this); 
     net.start(this); 
     isRunning = true; 
    } 

    public void start(LocationUpdateListener update) { 
     start(); 
     listener = update; 
    } 


    public void stop(){ 
     if(isRunning){ 
      gps.stop(); 
      net.stop(); 
      isRunning = false; 
      listener = null; 
     } 
    } 

    public boolean hasLocation(){ 
     //If either has a location, use it 
     return gps.hasLocation() || net.hasLocation(); 
    } 

    public boolean hasPossiblyStaleLocation(){ 
     //If either has a location, use it 
     return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation(); 
    } 

    public Location getLocation(){ 
     Location ret = gps.getLocation(); 
     if(ret == null){ 
      ret = net.getLocation(); 
     } 
     return ret; 
    } 

    public Location getPossiblyStaleLocation(){ 
     Location ret = gps.getPossiblyStaleLocation(); 
     if(ret == null){ 
      ret = net.getPossiblyStaleLocation(); 
     } 
     return ret; 
    } 

    public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) { 
     boolean update = false; 

     //We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale 
     if(lastLoc == null){ 
      update = true; 
     } 
     else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){ 
      update = true; 
     } 
     else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){ 
      update = true; 
     } 
     else if (newTime - lastTime > 5 * 60 * 1000){ 
      update = true; 
     } 

     if(update){ 
      if(listener != null){ 
       listener.onUpdate(lastLoc, lastTime, newLoc, newTime);     
      } 
      lastLoc = newLoc; 
      lastTime = newTime; 
     } 

    } 
} 

Поскольку оба варианта реализуют интерфейс LocationTracker, вы можете легко изменить свое мнение о том, какой из них использовать. Чтобы запустить класс в режиме опроса, просто вызовите start(). Чтобы запустить его в режиме обновления, запустите вызов (прослушиватель).

Также посмотрите на мои blog post по коду

+0

Для кого-то любопытного - причина, по которой я не использую время, встроенное в объект Location, заключается в том, что API не существует до API 17. Поскольку я хочу поддерживать совместимость с 14, я просто использую текущее время. Вот почему я не называю getLastKnownLocation раньше, потому что мы не можем получить время от него и посмотреть, не устареет ли его. –

+0

Ваш код - лучшее и самое полное решение, которое я нашел в последние два дня поиска по этой теме. Он работает без каких-либо ошибок и, как очарование, впечатляет. Только одна вещь, я изменил FallbackLocationTracker (контекст контекста, тип ProviderType) на public FallbackLocationTracker (контекст контекста), так как нам не нужно отправлять провайдера в этот класс, он учитывает как GPS, так и сеть, я прав? – zeeshan

+0

@zeeshan Вы правы, и я обновил код здесь. Я сделаю это на своем блоге в следующий раз, когда найду какое-то время (трудно получить ресурс для меня в эти дни). Как вы, наверное, догадались, я создал резервную копию, скопировав ее из другого класса и никогда не делал эту очистку. –

3

Для всего места проверки можно использовать следующий код. Вы можете поместить его в свой onStart() основного действия и отобразить диалоговое окно предупреждения, если return false.

private boolean isLocationAccurate() 
    { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) 
     { 
      String provider = Settings.Secure 
        .getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); 
      if (provider != null && !provider.contains("gps")) 
      { 
       return false; 
      } 
     } 
     else 
     { 
      try 
      { 
       int status = Settings.Secure 
         .getInt(this.getContentResolver(), Settings.Secure.LOCATION_MODE); 
       if (status != Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) 
       { 
        return false; 
       } 
      } 
      catch (Settings.SettingNotFoundException e) 
      { 
       Log.e(TAG, e.getMessage()); 
      } 
     } 

     return true; 
    } 
14

Получить расположение GPS от -

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

LocationListener locationListener = 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) { 
       // TODO Auto-generated method stub 
       double latitude = location.getLatitude(); 
       double longitude = location.getLongitude(); 
       double speed = location.getSpeed(); //spedd in meter/minute 
       speed = (speed*3600)/1000;  // speed in km/minute    Toast.makeText(GraphViews.this, "Current speed:" + location.getSpeed(),Toast.LENGTH_SHORT).show(); 
      } 
     }; 

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

} 
+2

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

+0

welcome @SmulianJulian –

+0

Как получить местоположение каждые 1 секунду –

12

Вы должны использовать новейшие/Новейший

GoogleApiClient Api

В основном то, что вам нужно сделать, это:

private GoogleApiClient mGoogleApiClient; 
mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addApi(LocationServices.API) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .build(); 

Тогда

@Override 
    public void onConnected(Bundle connectionHint) { 
     mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
       mGoogleApiClient); 
     if (mLastLocation != null) { 
      mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude())); 
      mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude())); 
     } 
    } 

для наиболее точного и надежного расположения. Смотрите мой пост здесь:

https://stackoverflow.com/a/33599228/2644905

Не используйте LocationListener, которая не является точной и отсроченной реакции. Честно говоря, это проще реализовать. прочитать также документацию: https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient

+1

Это лучший ответ для новейшего API. – dramzy

+0

Да. Это правильный способ сделать это в наши дни. @nickfox предоставил хорошие ссылки в [его втором ответе на этот вопрос] (http://stackoverflow.com/a/21545885/178433), от оригинальных создателей API сервисов местоположения, которые стоит проверить. – gMale

5

LocationManager является классом, который обеспечивает в сборке метода, чтобы получить последнюю знает место,

ШАГ 1: Создание LocationManager объекта, как показано ниже

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

ШАГ 2: Добавьте критерии

*Criteria is use for setting accuracy* 

Criteria criteria = new Criteria(); 
int currentapiVersion = android.os.Build.VERSION.SDK_INT; 

if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) { 

    criteria.setSpeedAccuracy(Criteria.ACCURACY_HIGH); 
    criteria.setAccuracy(Criteria.ACCURACY_FINE); 
    criteria.setAltitudeRequired(true); 
    criteria.setBearingRequired(true); 
    criteria.setSpeedRequired(true); 

} 

ШАГ 3: GET Имеющийся Provider

Threre два типа поставщика GPS и сети

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

ШАГ 4: Получить Последний Know Расположение

Location location = locationManager.getLastKnownLocation(provider); 

ШАГ 5: Получить широту и долготу

Если объект расположение является пустым, то Dont попытаться вызвать метод ниже с

getLatitude and getLongitude is methods which returns double values

34

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

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

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

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

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

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

Я использовал ваш метод для отображения координат, но я не могу видеть координаты Не могли бы вы заглянуть в мой [вопрос] (http://stackoverflow.com/q/42297618/6854117)? – faisal1208

+0

'mLocation' всегда дает null. Я попробовал то же, что упоминалось – DharanBro

+0

Перейдите по этой ссылке: http://demonuts.com/2016/12/30/get-current-gps-location-android-studio/ и загрузите исходный код оттуда и проверьте, не является ли исходный код работая на вашем компьютере или нет –

3

Я сделал проект, из которого мы можем получить точное местоположение, используя службы Google Play, GPS и сетевые провайдеры. Этот проект можно найти here.

Стратегия поиска наилучшего местоположения заключается в том, что сначала получить местоположение из сервисов google play, если местоположение найдено, а затем проверить погоду лучше или нет, если найденное местоположение является нулевым, перезапустите службы Google Play и попытайтесь найти местоположение с Android API местоположения. Зарегистрируйте местоположение на прослушивателях изменений, и когда когда-либо обнаружено лучшее местоположение, обратный вызов возвращает его в основное действие.

Он очень прост в использовании и реализации в коде только два класса, нам нужно вставлять т.е. LocationManagerInterfaceSmartLocationManager и, LocationActivity реализуют интерфейс и использование SmartLocationManager для извлечения местоположения.

/** 
* Created by Syed Raza Mehdi Naqvi on 8/10/2016. 
*/ 
public interface LocationManagerInterface { 
    String TAG = LocationManagerInterface.class.getSimpleName(); 

    void locationFetched(Location mLocation, Location oldLocation, String time, String locationProvider); 

} 

здесь класс менеджера места

import android.Manifest; 
import android.app.Activity; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.IntentSender; 
import android.content.pm.PackageManager; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.Build; 
import android.os.Bundle; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.app.AlertDialog; 
import android.util.Log; 
import android.widget.Toast; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.location.LocationListener; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 

import java.text.DateFormat; 
import java.util.Date; 

/** 
* Created by Syed Raza Mehdi Naqvi on 8/9/2016. 
*/ 
public class SmartLocationManager implements 
     GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { 

    private static final String TAG = SmartLocationManager.class.getSimpleName(); 

    private static final int TWO_MINUTES = 1000 * 60 * 2; 
    private static final int PERMISSION_REQUEST_CODE = 1000; 
    private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; 

    // default value is false but user can change it 
    private String mLastLocationUpdateTime;               // fetched location time 
    private String locationProvider;                // source of fetched location 

    private Location mLastLocationFetched;               // location fetched 
    private Location mLocationFetched;                // location fetched 
    private Location networkLocation; 
    private Location gpsLocation; 

    private int mLocationPiority; 
    private long mLocationFetchInterval; 
    private long mFastestLocationFetchInterval; 

    private Context mContext;                  // application context 
    private Activity mActivity;                  // activity context 
    private LocationRequest mLocationRequest; 
    private GoogleApiClient mGoogleApiClient; 
    private LocationManagerInterface mLocationManagerInterface; 

    private android.location.LocationManager locationManager; 
    private android.location.LocationListener locationListener; 

    boolean isGPSEnabled; 
    boolean isNetworkEnabled; 

    private int mProviderType; 
    public static final int NETWORK_PROVIDER = 1; 
    public static final int ALL_PROVIDERS = 0; 
    public static final int GPS_PROVIDER = 2; 

// private final double STANDARD_LOCATION_ACCURACY = 100.0; 
// private final double STANDARD_LOCATION_SEED_LIMIT = 6.95; 

    public static final int LOCATION_PROVIDER_ALL_RESTICTION = 1; 
    public static final int LOCATION_PROVIDER_RESTRICTION_NONE = 0; 
    public static final int LOCATION_PROVIDER_GPS_ONLY_RESTICTION = 2; 
    public static final int LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION = 3; 
    private int mForceNetworkProviders = 0; 

    public SmartLocationManager(Context context, Activity activity, LocationManagerInterface locationInterface, int providerType, int locationPiority, long locationFetchInterval, long fastestLocationFetchInterval, int forceNetworkProviders) { 
     mContext = context; 
     mActivity = activity; 
     mProviderType = providerType; 

     mLocationPiority = locationPiority; 
     mForceNetworkProviders = forceNetworkProviders; 
     mLocationFetchInterval = locationFetchInterval; 
     mFastestLocationFetchInterval = fastestLocationFetchInterval; 

     mLocationManagerInterface = locationInterface; 

     initSmartLocationManager(); 
    } 


    public void initSmartLocationManager() { 

     // 1) ask for permission for Android 6 above to avoid crash 
     // 2) check if gps is available 
     // 3) get location using awesome strategy 

     askLocationPermission();       // for android version 6 above 
     checkNetworkProviderEnable(mForceNetworkProviders);      // 

     if (isGooglePlayServicesAvailable())    // if googleplay services available 
      initLocationObjts();       // init obj for google play service and start fetching location 
     else 
      getLocationUsingAndroidAPI();     // otherwise get location using Android API 
    } 

    private void initLocationObjts() { 
     // Create the LocationRequest object 
     mLocationRequest = LocationRequest.create() 
       .setPriority(mLocationPiority) 
       .setInterval(mLocationFetchInterval)     // 10 seconds, in milliseconds 
       .setFastestInterval(mFastestLocationFetchInterval);  // 1 second, in milliseconds 

     if (mGoogleApiClient == null) { 
      mGoogleApiClient = new GoogleApiClient.Builder(mActivity) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(LocationServices.API) 
        .build(); 
     } 

     startLocationFetching();          // connect google play services to fetch location 
    } 

    @Override 
    public void onConnected(Bundle connectionHint) { 
     Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     startLocationUpdates(); 
     if (location == null) { 
      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
      getLocationUsingAndroidAPI(); 
     } else { 
      setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
     } 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     if (location == null) { 
      getLastKnownLocation(); 
     } else { 
      setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
     } 
    } 

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

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     if (connectionResult.hasResolution()) { 
      try { 
       connectionResult.startResolutionForResult(mActivity, CONNECTION_FAILURE_RESOLUTION_REQUEST); // Start an Activity that tries to resolve the error 
       getLocationUsingAndroidAPI();                // try to get location using Android API locationManager 
      } catch (IntentSender.SendIntentException e) { 
       e.printStackTrace(); 
      } 
     } else { 
      Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode()); 
     } 
    } 

    private void setNewLocation(Location location, Location oldLocation) { 
     if (location != null) { 
      mLastLocationFetched = oldLocation; 
      mLocationFetched = location; 
      mLastLocationUpdateTime = DateFormat.getTimeInstance().format(new Date()); 
      locationProvider = location.getProvider(); 
      mLocationManagerInterface.locationFetched(location, mLastLocationFetched, mLastLocationUpdateTime, location.getProvider()); 
     } 
    } 

    private void getLocationUsingAndroidAPI() { 
     // Acquire a reference to the system Location Manager 
     locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); 

     setLocationListner(); 
     captureLocation(); 
    } 

    public void captureLocation() { 
     if (Build.VERSION.SDK_INT >= 23 && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return; 
     } 
     try { 
      if (mProviderType == SmartLocationManager.GPS_PROVIDER) { 
       locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); 
      } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) { 
       locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 
      } else { 
       locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 
       locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); 
      } 
     } catch (Exception e) { 
      Log.e(TAG, e.getMessage()); 
     } 
    } 

    private void setLocationListner() { 
     // Define a listener that responds to location updates 
     locationListener = new android.location.LocationListener() { 
      public void onLocationChanged(Location location) { 
       // Called when a new location is found by the network location provider. 
       if (location == null) { 
        getLastKnownLocation(); 
       } else { 
        setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
//     if (isLocationAccurate(location) && location.getAccuracy() < STANDARD_LOCATION_ACCURACY && location.getSpeed() < STANDARD_LOCATION_SEED_LIMIT) {// no use of this if 
//      setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
//     } else { 
//      setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
//     } 
       } 
      } 

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

      public void onProviderEnabled(String provider) { 
      } 

      public void onProviderDisabled(String provider) { 
      } 
     }; 
    } 

    public Location getAccurateLocation() { 
     if (Build.VERSION.SDK_INT >= 23 && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return null; 
     } 
     try { 
      gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
      networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
      Location newLocalGPS, newLocalNetwork; 
      if (gpsLocation != null || networkLocation != null) { 
       newLocalGPS = getBetterLocation(mLocationFetched, gpsLocation); 
       newLocalNetwork = getBetterLocation(mLocationFetched, networkLocation); 
       setNewLocation(getBetterLocation(newLocalGPS, newLocalNetwork), mLocationFetched); 
      } 
     } catch (Exception ex) { 
      Log.e(TAG, ex.getMessage()); 
     } 
     return mLocationFetched; 
    } 

    protected void startLocationUpdates() { 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
    } 

    public void startLocationFetching() { 
     mGoogleApiClient.connect(); 
     if (mGoogleApiClient.isConnected()) { 
      startLocationUpdates(); 
     } 
    } 

    public void pauseLocationFetching() { 
     if (mGoogleApiClient.isConnected()) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
      mGoogleApiClient.disconnect(); 
     } 

    } 

    public void abortLocationFetching() { 
     mGoogleApiClient.disconnect(); 

     // Remove the listener you previously added 
     if (locationManager != null && locationListener != null) { 
      if (Build.VERSION.SDK_INT >= 23 && 
        ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
        ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
       return; 
      } 
      try { 
       locationManager.removeUpdates(locationListener); 
       locationManager = null; 
      } catch (Exception ex) { 
       Log.e(TAG, ex.getMessage()); 

      } 
     } 
    } 

    public void resetLocation() { 
     mLocationFetched = null; 
     mLastLocationFetched = null; 
     networkLocation = null; 
     gpsLocation = null; 
    } 

    // Android M Permission check 
    public void askLocationPermission() { 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 


      if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED 
        || ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED 
        ) { 
       if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) 
         || ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_FINE_LOCATION)) { 

        final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); 
        builder.setMessage("Please allow all permissions in App Settings for additional functionality.") 
          .setCancelable(false) 
          .setPositiveButton("Allow", new DialogInterface.OnClickListener() { 
           public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { 
            Toast.makeText(mContext, "Welcome", Toast.LENGTH_SHORT).show(); 
           } 
          }) 
          .setNegativeButton("Deny", new DialogInterface.OnClickListener() { 
           public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { 
            mActivity.finish(); 
           } 
          }); 
        final AlertDialog alert = builder.create(); 
        alert.show(); 

       } else 
        ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION 
          , Manifest.permission.ACCESS_FINE_LOCATION 
        }, PERMISSION_REQUEST_CODE); 

      } 
     } 
    } 

    public void checkNetworkProviderEnable(int enforceActive) { 
     locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); 

     isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
     isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

     if (!isGPSEnabled && !isNetworkEnabled) { 
      buildAlertMessageTurnOnLocationProviders("Your location providers seems to be disabled, please enable it", "OK", "Cancel"); 
     } else if (!isGPSEnabled && mForceNetworkProviders == LOCATION_PROVIDER_GPS_ONLY_RESTICTION) { 
      buildAlertMessageTurnOnLocationProviders("Your GPS seems to be disabled, please enable it", "OK", "Cancel"); 
     } else if (!isNetworkEnabled && mForceNetworkProviders == LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION) { 
      buildAlertMessageTurnOnLocationProviders("Your Network location provider seems to be disabled, please enable it", "OK", "Cancel"); 
     } 
     // getting network status 

     if (!isGPSEnabled && !isNetworkEnabled) { 
      Toast.makeText(mContext, "Location can't be fetched!", Toast.LENGTH_SHORT).show(); // show alert 
      mActivity.finish(); 
     } 
    } 

    private void buildAlertMessageTurnOnLocationProviders(String message, String positiveButtonText, String negativeButtonText) { 
     final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); 
     builder.setMessage(message) 
       .setCancelable(false) 
       .setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() { 
        public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { 
         Intent mIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
         mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
         mContext.startActivity(mIntent); 
        } 
       }) 
       .setNegativeButton(negativeButtonText, new DialogInterface.OnClickListener() { 
        public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { 
         mActivity.finish(); 
        } 
       }); 
     final AlertDialog alert = builder.create(); 
     alert.show(); 
    } 


    public Location getLastKnownLocation() { 
     locationProvider = LocationManager.NETWORK_PROVIDER; 
     Location lastKnownLocation = null; 
     // Or use LocationManager.GPS_PROVIDER 
     if (Build.VERSION.SDK_INT >= 23 && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return lastKnownLocation; 
     } 
     try { 
      lastKnownLocation = locationManager.getLastKnownLocation(locationProvider); 
      return lastKnownLocation; 
     } catch (Exception e) { 
      Log.e(TAG, e.getMessage()); 
     } 
     return lastKnownLocation; 
    } 

    public boolean isGooglePlayServicesAvailable() { 
     int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext); 

     if (status == ConnectionResult.SUCCESS) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    /** 
    * 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 Location getBetterLocation(Location location, Location currentBestLocation) { 
     if (currentBestLocation == null) { 
      // A new location is always better than no location 
      return location; 
     } 

     // 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 location; 
      // If the new location is more than two minutes older, it must be worse 
     } else if (isSignificantlyOlder) { 
      return currentBestLocation; 
     } 

     // 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 location; 
     } else if (isNewer && !isLessAccurate) { 
      return location; 
     } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 
      return location; 
     } 
     return currentBestLocation; 
    } 

    /** 
    * Checks whether two providers are the same 
    */ 

    private boolean isSameProvider(String provider1, String provider2) { 
     if (provider1 == null) { 
      return provider2 == null; 
     } 
     return provider1.equals(provider2); 
    } 

    public boolean isLocationAccurate(Location location) { 
     if (location.hasAccuracy()) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public Location getStaleLocation() { 
     if (mLastLocationFetched != null) { 
      return mLastLocationFetched; 
     } 
     if (Build.VERSION.SDK_INT >= 23 && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return null; 
     } 
     if (mProviderType == SmartLocationManager.GPS_PROVIDER) { 
      return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
     } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) { 
      return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
     } else { 
      return getBetterLocation(locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER), locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)); 
     } 
    } 
} 

мы можем использовать его с активностью или фрагментом, здесь я использую его с активностью

import android.location.Location; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.example.raza.locationaware.location.LocationManagerInterface; 
import com.example.raza.locationaware.location.SmartLocationManager; 
import com.google.android.gms.location.LocationRequest; 

public class LocationActivity extends AppCompatActivity implements LocationManagerInterface { 

    public static final String TAG = LocationActivity.class.getSimpleName(); 

    SmartLocationManager mLocationManager; 
    TextView mLocalTV, mLocationProviderTV, mlocationTimeTV; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_location); 
     mLocationManager = new SmartLocationManager(getApplicationContext(), this, this, SmartLocationManager.ALL_PROVIDERS, LocationRequest.PRIORITY_HIGH_ACCURACY, 10 * 1000, 1 * 1000, SmartLocationManager.LOCATION_PROVIDER_RESTRICTION_NONE); // init location manager 
     mLocalTV = (TextView) findViewById(R.id.locationDisplayTV); 
     mLocationProviderTV = (TextView) findViewById(R.id.locationProviderTV); 
     mlocationTimeTV = (TextView) findViewById(R.id.locationTimeFetchedTV); 
    } 

    protected void onStart() { 
     super.onStart(); 
     mLocationManager.startLocationFetching(); 
    } 

    protected void onStop() { 
     super.onStop(); 
     mLocationManager.abortLocationFetching(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     mLocationManager.pauseLocationFetching(); 
    } 

    @Override 
    public void locationFetched(Location mLocal, Location oldLocation, String time, String locationProvider) { 
     Toast.makeText(getApplication(), "Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude(), Toast.LENGTH_LONG).show(); 
     mLocalTV.setText("Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude()); 
     mLocationProviderTV.setText(locationProvider); 
     mlocationTimeTV.setText(time); 
    } 
} 

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

4

Простейшее вы можете найти

package com.javapapers.android.geolocationfinder; 

    import android.os.Bundle; 
    import android.app.Activity; 
    import android.content.Context; 
    import android.location.Location; 
    import android.location.LocationListener; 
    import android.location.LocationManager; 
    import android.widget.TextView; 

    import android.util.Log; 

    public class MainActivity extends Activity implements LocationListener{ 
    protected LocationManager locationManager; 
    protected LocationListener locationListener; 
    protected Context context; 
    TextView txtLat; 
    String lat; 
    String provider; 
    protected String latitude,longitude; 
    protected boolean gps_enabled,network_enabled; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    txtLat = (TextView) findViewById(R.id.textview1); 

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); 
    } 
    @Override 
    public void onLocationChanged(Location location) { 
    txtLat = (TextView) findViewById(R.id.textview1); 
    txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude()); 
    } 

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

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

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

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

Вы можете проверить здесь: https://github.com/julioromano/RxLocation и использовать его или его исходный код в качестве примеров для вашей реализации.

+0

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

+0

@AsifAli Если вы обнаружили ошибку, пожалуйста, откройте проблему или отправьте PR. –

5

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

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

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

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

requestSingleLocationFix(easyLocationRequest); 

или

requestLocationUpdates(easyLocationRequest); 

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

1

Простой Найти писать код в On Местонахождение Метод

public void onLocationChanged(Location location) { 
    if (mCurrLocationMarker != null) { 
     mCurrLocationMarker.remove(); 
    } 


    //Place current location marker 
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); 
    MarkerOptions markerOptions = new MarkerOptions(); 
    markerOptions.position(latLng); 
    markerOptions.title("Current Position"); 
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); 
    mCurrLocationMarker = mMap.addMarker(markerOptions); 

    //move map camera 
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 
    mMap.animateCamera(CameraUpdateFactory.zoomTo(18)); 

    PolylineOptions pOptions = new PolylineOptions() 
      .width(5) 
      .color(Color.GREEN) 
      .geodesic(true); 
    for (int z = 0; z < routePoints.size(); z++) { 
     LatLng point = routePoints.get(z); 
     pOptions.add(point); 
    } 
    line = mMap.addPolyline(pOptions); 
    routePoints.add(latLng); 
} 
5

GoogleSamples имеет подробный пример, используя последний FusedLocationProviderApi. К сожалению, большинство утвержденных ответов устарели.

Выполните приведенные ниже примеры для реализации Location Services с помощью FusedLocationProviderApi

https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates

https://github.com/googlesamples/android-play-location/blob/master/LocationUpdates/app/src/main/java/com/google/android/gms/location/sample/locationupdates/MainActivity.java

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