Cách đơn giản và mạnh mẽ nhất để có được vị trí hiện tại của người dùng trên Android là gì?


811

Các LocationManager API trên Android có vẻ như đó là một chút của một nỗi đau để sử dụng cho một ứng dụng mà chỉ cần một xấp xỉ thường xuyên và sơ bộ vị trí của người dùng.

Ứng dụng tôi đang làm việc không thực sự là một ứng dụng vị trí, nhưng nó cần có được vị trí của người dùng để hiển thị danh sách các doanh nghiệp gần đó. Không cần phải lo lắng về việc người dùng sẽ di chuyển xung quanh hay bất cứ điều gì tương tự.

Đây là những gì tôi muốn làm:

  1. Hiển thị cho người dùng một danh sách các địa điểm gần đó.
  2. Tải trước vị trí của người dùng để đến lúc tôi cần Activity X, nó sẽ khả dụng.
  3. Tôi không đặc biệt quan tâm đến độ chính xác hoặc tần suất cập nhật. Chỉ cần lấy một vị trí là đủ miễn là nó không tắt. Có lẽ nếu tôi muốn trở nên lạ mắt, tôi sẽ cập nhật vị trí cứ sau vài phút hoặc lâu hơn, nhưng đó không phải là ưu tiên lớn.
  4. Hoạt động cho mọi thiết bị miễn là có nhà cung cấp GPS hoặc Nhà cung cấp vị trí mạng.

Có vẻ như điều đó không khó lắm, nhưng dường như tôi phải quay vòng hai nhà cung cấp vị trí khác nhau (GPS và NETWORK) và quản lý vòng đời của mỗi người. Không chỉ vậy, tôi còn phải sao chép cùng một mã trong nhiều hoạt động để đáp ứng # 2. Trước đây tôi đã từng sử dụng getBestProvider()để cắt giảm giải pháp xuống chỉ sử dụng một nhà cung cấp vị trí, nhưng dường như điều đó chỉ mang đến cho bạn nhà cung cấp "lý thuyết" tốt nhất chứ không phải nhà cung cấp thực sự sẽ mang lại cho bạn kết quả tốt nhất.

Có cách nào đơn giản hơn để thực hiện điều này?


5
Tại đây bạn có thể tìm thấy hướng dẫn từng bước với mã mẫu cho GPS, chúc mừng !!
swiftBoy

1
Bạn có thể sử dụng một thư viện đơn giản tóm tắt tất cả những điều phải xảy ra "dưới mui xe": github.com/delight-im/Android-SimpleLocation
caw

Vào năm 2018 nó FusedLocationProviderClient Ví dụ cho nền cập nhật vị trí freakyjolly.com/...
Mã Spy

nhận câu trả lời trong Kotlin tại đây: stackoverflow.com/a/53800632/2201814
MHSFisher 16/12/18

bạn có thể sử dụng các kỹ thuật chụp vị trí hợp nhất trong Android.
SIVAKUMAR.J

Câu trả lời:


946

Đây là những gì tôi làm:

  1. Trước hết tôi kiểm tra những nhà cung cấp được kích hoạt. Một số có thể bị vô hiệu hóa trên thiết bị, một số có thể bị vô hiệu hóa trong bảng kê khai ứng dụng.
  2. Nếu có bất kỳ nhà cung cấp nào, tôi bắt đầu nghe vị trí và hẹn giờ hết giờ. Ví dụ của tôi là 20 giây, có thể không đủ cho GPS để bạn có thể phóng to nó.
  3. Nếu tôi nhận được cập nhật từ trình nghe vị trí, tôi sử dụng giá trị được cung cấp. Tôi dừng nghe và hẹn giờ.
  4. Nếu tôi không nhận được bất kỳ cập nhật và thời gian trôi qua, tôi phải sử dụng các giá trị được biết đến cuối cùng.
  5. Tôi lấy các giá trị được biết đến cuối cùng từ các nhà cung cấp có sẵn và chọn những giá trị gần đây nhất.

Đây là cách tôi sử dụng lớp học của mình:

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

Và đây là lớp 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);
    }
}

Ai đó cũng có thể muốn sửa đổi logic của tôi. Ví dụ: nếu bạn nhận được cập nhật từ nhà cung cấp mạng, đừng dừng người nghe mà tiếp tục chờ đợi. GPS cung cấp dữ liệu chính xác hơn vì vậy nó đáng để chờ đợi. Nếu hết giờ và bạn đã nhận được cập nhật từ Mạng nhưng không phải từ GPS thì bạn có thể sử dụng giá trị được cung cấp từ Mạng.

Một cách tiếp cận khác là sử dụng LocationClient http://developer.android.com/training/location/retrieve-civerse.html . Nhưng nó yêu cầu apk Google Play Services phải được cài đặt trên thiết bị người dùng.


7
Đối với hồ sơ, sự hiểu biết của tôi là google thường khuyên bạn không nên sử dụng android: configChanges. Thay vào đó, tôi đã đi với một giải pháp đăng ký các mốc thời gian và hủy bỏ chúng trênDestroy.
emmby

5
Đã sử dụng lớp này trong ứng dụng đơn giản của tôi và nó hoạt động như một nhà vô địch. Cảm ơn đã đăng nó!
Alex Pritchard

46
Nó hiệu quả tuyệt vời đối với tôi! Tuy nhiên, hoạt động tôi sử dụng này cho tôi kiểm tra vị trí trong sơ yếu lý lịch. Nếu người dùng rút lui khỏi hoạt động trước khi trả lại vị trí, ứng dụng sẽ bị sập. Tôi đã sửa lỗi này bằng cách thêm phương thức này vào MyLocation class.public void CancTimer () {timer1.celon (); lm.removeUpdates (locationListenerGps); lm.removeUpdates (locationListenerNetwork); } Tôi gọi đây là onPause () và nó đã khắc phục sự cố.
dbaugh

14
Hey tôi có thể sử dụng mã của bạn trong ứng dụng của tôi cho mục đích thương mại. Nếu bạn có bất kỳ khiếu nại về điều đó xin vui lòng cho tôi biết.
TRonZ

87
@TRonZ Không có vấn đề, xin vui lòng sử dụng nó trong bất kỳ mục đích nào.
Fedor

43

Sau khi tìm kiếm cách triển khai tốt nhất làm thế nào để có được vị trí người dùng chính xác nhất, tôi đã quản lý để kết hợp tất cả các phương thức tốt nhất và đưa ra lớp sau:

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

Lớp này cố gắng kết nối với min_gps_sat_countcác vệ tinh nếu GPS được bật. Khác trả lại LocationManager.getBestProvider()vị trí. Kiểm tra mã!


2
Nó sẽ dừng lại sau 1 phút hoặc khi nó sẽ tìm thấy vị trí.
wormhit

@wormhit Trong trường hợp của tôi, nó không dừng lại sau 120 lần đếm. Tôi đã kích hoạt GPS và nhà cung cấp mạng cũng có sẵn Tôi cũng đã thêm permissio thích hợp trong tệp Menifest.
Narendra Pal

Chỉ cần đặt những thứ này dưới dạng nhập khẩu:import java.util.Iterator; import android.content.Context; import android.location.Criteria; import android.location.GpsSatellite; import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.Handler;
Thành Long

31

Với giải pháp của Fedor, tôi đã trải nghiệm nhiều lần thực hiện cuộc gọi lại gotLocation. Có vẻ là do điều kiện cuộc đua trong LocationListener.onLocationChangedphương thức bị ghi đè , khi phương thức gotLocation là 'đủ dài' . Tôi không chắc chắn, nhưng tôi đoán removeUpdatesngăn chặn việc nhập các tin nhắn mới trong hàng đợi Looper, nhưng nó không loại bỏ những tin nhắn đã được đăng ký nhưng chưa được sử dụng. Do đó điều kiện cuộc đua.

Để giảm khả năng xảy ra hành vi sai này, có thể gọi removeUpdates trước khi phát sinh sự kiện onLocationChanged, nhưng chúng ta vẫn có điều kiện cuộc đua.

Giải pháp tốt nhất tôi tìm thấy là thay thế requestLocationUpdatesbằng requestSingleUpdate.

Đây là phiên bản của tôi, dựa trên giải pháp của Fedor, sử dụng Trình xử lý để gửi tin nhắn đến chuỗi xử lý:

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

Tôi sử dụng lớp này từ một chủ đề looper tùy chỉnh, như sau:

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

Trong đó Tọa độ là một lớp đơn giản với hai thuộc tính: vĩ độ và kinh độ.


4
Tuy nhiên, điểm thú vị là requestSingleUpdate yêu cầu API cấp 9. Nhưng +1 để chỉ ra điều đó.
Eduardo

@Eduardo: một khả năng khác là thực thi mã của tác vụ bằng cách sử dụng Trình xử lý được liên kết với trình xử lý và gọi nó bằng cách gửi một thông báo (trống) đến trình xử lý. Vì các tin nhắn được tuần tự hóa trên hàng đợi looper, bạn có thể xóa thủ công (ví dụ: sử dụng cờ) điều kiện cuộc đua. Điều đó không yêu cầu API Livel 9, nhưng nó cần sử dụng rõ ràng bộ xử lý.
differenziale

17

Tôi đã tạo một ứng dụng nhỏ với mô tả từng bước để có được vị trí hiện tại tọa độ GPS.

nhập mô tả hình ảnh ở đây

Hoàn thành mã nguồn ví dụ trong URL dưới đây:


Nhận tọa độ Vị trí hiện tại, Tên thành phố - trong Android


Xem làm thế nào nó hoạt động :

  • Tất cả những gì chúng ta cần làm là thêm quyền này vào tệp kê khai

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">  
    </uses-permission>
  • và tạo cá thể LocationManager như thế này

    LocationManager locationManager = (LocationManager) 
                                      getSystemService(Context.LOCATION_SERVICE);
  • Kiểm tra GPS có được bật hay không

  • sau đó triển khai LocationListener và Nhận tọa độ

    LocationListener locationListener = new MyLocationListener();  
    locationManager.requestLocationUpdates(  
    LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
  • đây là mã mẫu để làm


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

1
vị trí cần phải được thay đổi. không phải trong khi đứng

15

Bạn luôn có thể chỉ sử dụng LocationManager.getLastKnownLocation () nhưng giống như nó nói rằng nó có thể đã lỗi thời.

Và một cách đơn giản để có được vị trí chung có thể là đăng ký mạng (thường khá nhanh).

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

và sau đó làm

locationManager.removeUpdates(this);

trong onLocationChanged()phương pháp của người nghe.


Cảm ơn BrennaSoft. Tôi đã thấy rằng getLastKnownLocation () thường có thể bị tắt một cách dữ dội và do đó không thực sự hoạt động như một giải pháp độc lập. Ngoài ra, tôi không rõ ràng rằng chỉ dựa vào NETWORK_PROVIDER sẽ hoạt động, vì nhiều khu vực của đất nước không có tọa độ GPS rất tốt cho các điểm truy cập wifi (và tôi không biết về tháp di động)
emmby

9

Tôi đã viết hướng dẫn chi tiết về vị trí hiện tại ở đây trên demuts.com . Bạn có thể tìm thêm mô tả ở đây và bạn cũng có thể tải xuống toàn bộ mã nguồn demo để hiểu rõ hơn.

Đã có nhiều câu trả lời ở đó nhưng tôi muốn chỉ ra cách mới nhất để có được vị trí bằng Google API, vì vậy các lập trình viên mới có thể sử dụng phương pháp mới:

Trước hết, đặt nó trong tập tin gradle

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

sau đó thực hiện các giao diện cần thiết

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

khai báo

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

đặt cái này vào onCreate()

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

Cuối cùng, ghi đè các phương thức cần thiết

 @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) {

    }

Đừng quên khởi động GPS trong thiết bị của bạn trước khi chạy ứng dụng.


Sử dụng API? Vì vậy, đây là dịch vụ được giới hạn tỷ lệ ngay.
3304007

8

Thực tế chúng ta có thể sử dụng hai nhà cung cấp (GPS & NETWORK). Và họ chỉ chia sẻ một người nghe công khai:

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

Điều này là cần thiết bởi vì OnLocationChanged()phương thức luôn cần được gọi kịp thời.


5

Tôi không chắc liệu Dịch vụ dựa trên vị trí có thể lấy vị trí từ các cơ sở hạ tầng khác ngoài GPS hay không, nhưng theo bài viết đó, có vẻ như có thể:

Các ứng dụng có thể gọi bất kỳ loại phương pháp định vị nào.

Sử dụng mạng điện thoại di động: ID di động hiện tại có thể được sử dụng để xác định Trạm thu phát cơ sở (BTS) mà thiết bị đang liên lạc và vị trí của trạm BTS đó. Rõ ràng, độ chính xác của phương pháp này phụ thuộc vào kích thước của ô và có thể khá không chính xác. Một tế bào GSM có thể có đường kính từ 2 đến 20 km. Các kỹ thuật khác được sử dụng cùng với ID tế bào có thể đạt được độ chính xác trong vòng 150 mét.

Sử dụng các vệ tinh: Hệ thống định vị toàn cầu (GPS), do Bộ Quốc phòng Hoa Kỳ kiểm soát, sử dụng một chòm sao gồm 24 vệ tinh quay quanh trái đất. GPS xác định vị trí của thiết bị bằng cách tính toán sự khác biệt về thời gian tín hiệu từ các vệ tinh khác nhau thực hiện để đến được máy thu. Tín hiệu GPS được mã hóa, do đó thiết bị di động phải được trang bị máy thu GPS. GPS có khả năng là phương pháp chính xác nhất (từ 4 đến 40 mét nếu máy thu GPS nhìn rõ bầu trời), nhưng nó có một số nhược điểm: Phần cứng bổ sung có thể tốn kém, tiêu tốn pin trong khi sử dụng và cần một chút ấm sau khi bắt đầu lạnh để có được một sửa chữa ban đầu trên các vệ tinh có thể nhìn thấy. Nó cũng bị "hiệu ứng hẻm núi" trong các thành phố, nơi tầm nhìn vệ tinh không liên tục.

Sử dụng đèn hiệu định vị tầm ngắn: Trong các khu vực tương đối nhỏ, chẳng hạn như một tòa nhà, mạng cục bộ có thể cung cấp vị trí cùng với các dịch vụ khác. Ví dụ: các thiết bị được trang bị phù hợp có thể sử dụng Bluetooth để định vị tầm ngắn.


1
@ElijahSaounkine rõ ràng npinti chưa nghe nói về GPS có Hỗ trợ. Trong tương lai, có lẽ bạn chỉ có thể thông báo cho mọi người về những điều họ đã giám sát, thay vì tích cực về nó.
saltandpepper

@Sammy 5 năm trước tôi dường như đã nhảy hơn nhiều so với bây giờ. "Tương lai" mà bạn đề cập, liên quan đến ghi chú của tôi, có lẽ đã bắt đầu và kết thúc;)
Elijah Saounkine

5

Sử dụng mã dưới đây, nó sẽ cung cấp cho nhà cung cấp tốt nhất có sẵn:

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

Cách khởi tạo ctx, Bối cảnh ctx = này; ? nó bị sập

4

Cách được đề xuất để làm điều này là sử dụng LocationClient :

Đầu tiên, xác định giá trị khoảng thời gian cập nhật vị trí. Điều chỉnh điều này theo nhu cầu của bạn.

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;

Có bạn Activity thực hiện GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListenerLocationListener.

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

Sau đó, thiết lập một LocationClient trong những onCreate()phương pháp của bạn 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);
}

Thêm các phương thức cần thiết vào của bạn Activity ; onConnected()là phương thức được gọi khi LocationClientkết nối. onLocationChanged()là nơi bạn sẽ truy xuất vị trí cập nhật nhất.

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

Đảm bảo kết nối / ngắt kết nối LocationClientđể nó chỉ sử dụng thêm pin khi thực sự cần thiết và vì vậy GPS không chạy vô thời hạn. Các LocationClientphải được kết nối để lấy dữ liệu từ nó.

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

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

Nhận vị trí của người dùng. Trước tiên hãy thử sử dụng LocationClient; Nếu thất bại, rơi trở lại 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;
        }
    }
}

3

Mặc dù câu trả lời đã được đưa ra ở đây. Tôi chỉ muốn chia sẻ điều này với thế giới trong trường hợp xảy ra tình huống như vậy.

Yêu cầu của tôi là tôi cần có được vị trí hiện tại của người dùng trong vòng tối đa 30 đến 35 giây, vì vậy đây là giải pháp tôi đã thực hiện sau Câu trả lời của Nirav Ranpara .

1. Tôi đã tạo lớp MyLocationManager.java xử lý tất cả các công cụ GPS và Mạng

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. Tôi đã tạo Giao diện (gọi lại) OnLocationDetectectionListener.java để truyền kết quả trở lại cho đoạn gọi hoặc hoạt động

import android.location.Location;

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

3. Sau đó, tôi đã tạo một Hoạt động MainAppActivty.java thực hiện OnLocationDetectectionListenergiao diện và đây là cách tôi nhận vị trí của mình trong đó

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. Thêm các quyền sau vào tệp kê khai của bạn

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

Hy vọng điều này hữu ích cho người khác :)


3

Từ hơn một năm trước, tôi đã sử dụng kết hợp GPS_PROVIDER và NETWORK_PROVIDER để có được vị trí hiện tại và nó hoạt động tốt, nhưng từ vài tháng trước, tôi đã nhận được vị trí sau một thời gian trì hoãn, vì vậy tôi đã chuyển sang API mới nhất FuseLocationProviderClient và nó hoạt động khá tốt

Đây là lớp mà tôi đã viết để có được vị trí hiện tại bằng cách sử dụng FuseLocationProviderClient. Trong đoạn mã dưới đây, tôi đã sử dụng bộ hẹn giờ để chờ trong khi nhận được vị trí hiện tại, tôi đã lên lịch hẹn giờ chậm 15 giây, bạn có thể thay đổi nó theo bạn.

private static FusedLocationService ourInstance;
private final LocationRequest locationRequest;
private FusedLocationProviderClient mFusedLocationClient;
private Location mLastLocation;
private Context context;
private FindOutLocation findOutLocation;
private boolean callbackTriggered = false;
private Timer timer;

public static FusedLocationService getInstance(Context pContext) {

    if (null == ourInstance) ourInstance = new FusedLocationService(pContext);

    return ourInstance;
}

private FusedLocationService(Context pContext) {
    context = pContext;
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
    locationRequest = getLocationRequest();
    requestLocation(context);
}

public Location getLastKnownLocation() {
    return mLastLocation;
}

private void requestLocation(Context context) {

    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    mFusedLocationClient.requestLocationUpdates(locationRequest, mLocationCallback, null);
    mFusedLocationClient.getLastLocation().addOnSuccessListener(location -> {
        if (location != null) {
            mLastLocation = location;
            triggerCallback(mLastLocation);
        }
    });
}

private LocationRequest getLocationRequest() {
    LocationRequest locationRequest = new LocationRequest();
    long INTERVAL = 10 * 1000;
    long FASTEST_INTERVAL = 5 * 1000;
    locationRequest.setInterval(INTERVAL);
    locationRequest.setFastestInterval(FASTEST_INTERVAL);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    return locationRequest;
}

private LocationCallback mLocationCallback = new LocationCallback() {
    @Override
    public void onLocationResult(LocationResult locationResult) {
        for (Location location : locationResult.getLocations()) {
            if (location != null) mLastLocation = location;
        }
        if (null != mLastLocation) triggerCallback(mLastLocation);
    }
};

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

@SuppressLint("MissingPermission")
public void findLocation(FindOutLocation findOutLocation) {
    long TIMER_TIME_OUT = 15 * 1000;
    this.findOutLocation = findOutLocation;
    callbackTriggered = false;

    try {
        requestLocation(context);
        timer = new Timer();
        timer.schedule(new GetLastLocation(context), TIMER_TIME_OUT);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private class GetLastLocation extends TimerTask {
    Context context;

    GetLastLocation(Context context) {
        this.context = context;
    }

    @Override
    public void run() {
        triggerCallback(mLastLocation);
    }
}

private void triggerCallback(Location location) {
    if (null != location) mLastLocation = location;
    if (!callbackTriggered && null != findOutLocation) {
        callbackTriggered = true;
        removeLocationUpdates();
        findOutLocation.gotLocation(location);
        findOutLocation = null;
    }
}

private void removeLocationUpdates() {
    if (null != timer) timer.cancel();
    if (null != mFusedLocationClient)
        mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
}

Và được gọi là từ hoạt động, đây là mã

    FusedLocationService.FindOutLocation findOutLocation = new FusedLocationService.FindOutLocation() {
        @Override
        public void gotLocation(Location currentLocation) {
            if (currentLocation != null) {
                /*TODO DO SOMETHING WITH CURRENT LOCATION*/
            }
        }
    };
    FusedLocationService.getInstance(this).findLocation(findOutLocation);

Thêm các mục sau trong AndroidManifest.xml

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

<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
<uses-feature android:name="android.hardware.location.gps" />

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

2

Đây là mã cung cấp vị trí hiện tại của người dùng

tạo Bản đồ kích hoạt:

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

tệp chính:

    <?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>

và xác định sự cho phép sau đây trong bảng kê khai:

<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"/>

2

Đây là cách tôi yêu cầu Quyền của người dùng.

Bên ngoài thẻ ứng dụng của bạn trong AndroidManifest.xml thêm các yêu cầu cấp phép này.

<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" />

Sau đó, thêm các phụ thuộc Vị trí của Google vào tệp Ứng dụng.

implementation 'com.google.android.gms:play-services-location:15.0.0'

Bây giờ khai báo một số biến toàn cầu.

private lateinit var mFusedLocationProvider:FusedLocationProviderClient
private lateinit var mLocationCallback: LocationCallback
private lateinit var mLocationRequest: LocationRequest
private var mLocationPermissionGranted:Boolean = false

Trong phương thức OnCreate của Hoạt động của bạn (Tôi không thể định dạng đúng mã, xin lỗi vì điều đó)

mFusedLocationProvider = LocationServices.getFusedLocationProviderClient(this)

//Location Callback
mLocationCallback = object: LocationCallback(){
 override fun onLocationResult(p0: LocationResult?) {
  if(p0==null){
     //todo(request user to enable location from settings then remove return)
     return
  }else{
      getDeviceLocation()
       }
  }
}

//Location Request
mLocationRequest = LocationRequest.create()
mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
//Set the Interval for Latest Interval Update
mLocationRequest.interval = 5000
//Set How Many Location Updated you Want
mLocationRequest.numUpdates = 1

getLocationPermission()
getDeviceLocation()

Bây giờ tạo cả hai chức năng.

 private fun getLocationPermission() {

            val permission:Array<String> = arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION,android.Manifest.permission.ACCESS_COARSE_LOCATION)
            if(ContextCompat.checkSelfPermission(applicationContext,Constant.FINE_LOCATION)== PermissionChecker.PERMISSION_GRANTED){
                if(ContextCompat.checkSelfPermission(applicationContext,Constant.COARSE_LOCATION)== PermissionChecker.PERMISSION_GRANTED){
                    mLocationPermissionGranted = true
                }
            }else{
                ActivityCompat.requestPermissions(this,permission,Constant.LOCATION_REQUEST_CODE)
            }

    }

Phương pháp thứ hai

private fun getDeviceLocation() {
        try{
            if(mLocationPermissionGranted){

                mFusedLocationProvider.lastLocation.addOnCompleteListener(this,{task: Task<Location> ->
                    if(task.isSuccessful){
                        var currentLocation: Location? = task.result
                        if(currentLocation!=null){

                            Log.i("Location","Latitude is ${currentLocation.latitude} and Longitude" +
                                    "${currentLocation.longitude}")
                        }

                        else
                            mFusedLocationProvider.requestLocationUpdates(mLocationRequest,mLocationCallback,null)
                    }
                })
            }
        }catch (e:SecurityException){
            Log.e("Error", "Security Exception ${e.message}")
        }
    }

Đối với Constant.kt

class Constant{
    companion object {

        //Location Request Settings
        const val SET_INTERVAL:Long = 2000
        const val NUM_UPDATES:Int = 1

        //Location Permission
        const val FINE_LOCATION:String = android.Manifest.permission.ACCESS_FINE_LOCATION
        const val COARSE_LOCATION:String = android.Manifest.permission.ACCESS_COARSE_LOCATION
    }
}

2

Những cải tiến đối với giải pháp của @ Fedor. Thay vì yêu cầu vị trí với khoảng thời gian '0' và khoảng cách '0', chúng tôi có thể sử dụng phương thức requestSingleUpdate của người quản lý vị trí . Mã cập nhật (phiên bản kotlin)

import android.annotation.SuppressLint
import android.content.Context
import android.location.Criteria
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Bundle
import java.util.*

@SuppressLint("MissingPermission")
class AppLocationProvider {

  private lateinit var timer: Timer
  private var locationManager: LocationManager? = null
  private lateinit var locationCallBack: LocationCallBack
  private var gpsEnabled = false
  private var networkEnabled = false

  private var locationListener: LocationListener = object : LocationListener {

    override fun onLocationChanged(location: Location) {
      timer.cancel()
      locationCallBack.locationResult(location)
    }

    override fun onProviderDisabled(provider: String) {}
    override fun onProviderEnabled(provider: String) {}
    override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
  }

  fun getLocation(context : Context, callBack: LocationCallBack): Boolean {
    locationCallBack = callBack
    if (locationManager == null)
      locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager?

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

    try {
      networkEnabled = locationManager!!.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
    } catch (ex: Exception) {
      ex.printStackTrace()
    }

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

    val criteria = Criteria()
    if (gpsEnabled) {
      criteria.accuracy = Criteria.ACCURACY_FINE
    } else {
      criteria.accuracy = Criteria.ACCURACY_COARSE
    }
    locationManager!!.requestSingleUpdate(criteria, locationListener, null)

    timer = Timer()
    timer.schedule(GetLastKnownLocation(), 5000)
    return true
  }

  inner class GetLastKnownLocation : TimerTask() {

    override fun run() {
      locationManager!!.removeUpdates(locationListener)

      var netLoc: Location? = null
      var gpsLoc: Location? = null

      if (gpsEnabled)
        gpsLoc = locationManager!!.getLastKnownLocation(LocationManager.GPS_PROVIDER)
      if (networkEnabled)
        netLoc = locationManager!!.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)

      //check which value use the latest one
      if (gpsLoc != null && netLoc != null) {
        if (gpsLoc.time > netLoc.time)
          locationCallBack.locationResult(gpsLoc)
        else
          locationCallBack.locationResult(netLoc)
        return
      }

      if (gpsLoc != null) {
        locationCallBack.locationResult(gpsLoc)
        return
      }
      if (netLoc != null) {
        locationCallBack.locationResult(netLoc)
        return
      }
      locationCallBack.locationResult(null)
    }
  }

  interface LocationCallBack {
    fun locationResult(location: Location?)
  }
}

Để có được vị trí cần chỉ cần gọi phương thức getLocation là -

AppLocationProvider().getLocation(context, object : AppLocationProvider.LocationCallBack {
  override fun locationResult(location: Location?) {
    // use location, this might get called in a different thread if a location is a last known location. In that case, you can post location on main thread
  }
})

Lưu ý: Trước khi gọi phương thức getLocation, phải có sự cho phép vị trí bắt buộc.


1

Để có được và hiển thị vị trí hiện tại của người dùng, bạn cũng có thể sử dụng MyLocationOverlay. Giả sử bạn có một mapViewlĩnh vực trong hoạt động của bạn. Tất cả những gì bạn cần làm để hiển thị vị trí người dùng là như sau:

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

Điều này có được vị trí hiện tại từ GPS hoặc mạng. Nếu cả hai đều thất bại, enableMyLocation()sẽ trở lạifalse .

Đối với các vị trí của những thứ xung quanh khu vực, ItemizedOverlaynên làm một mẹo.

Tôi hy vọng tôi đã không hiểu nhầm câu hỏi của bạn. Chúc may mắn.


2
Cảm ơn bạn. Câu hỏi đặt ra là các hoạt động không có chế độ xem bản đồ và không cần hiển thị vị trí cho người dùng.
emmby

1

EDIT: Được cập nhật với API dịch vụ vị trí mới nhất từ thư viện Google Play Services (tháng 7 năm 2014)

Tôi sẽ khuyên bạn nên sử dụng API dịch vụ vị trí mới , có sẵn từ thư viện Dịch vụ Google Play, cung cấp khung công tác cấp cao, mạnh mẽ hơn, tự động hóa các tác vụ như lựa chọn nhà cung cấp vị trí và quản lý nguồn. Theo tài liệu chính thức: "... API vị trí giúp bạn dễ dàng xây dựng các ứng dụng nhận biết vị trí, mà không cần phải tập trung vào các chi tiết của công nghệ vị trí cơ bản. Chúng cũng cho phép bạn giảm thiểu mức tiêu thụ điện bằng cách sử dụng tất cả các khả năng của phần cứng thiết bị. "

Để biết thêm thông tin, hãy truy cập: Làm cho ứng dụng của bạn xác định vị trí

Để xem ví dụ đầy đủ bằng cách sử dụng API Dịch vụ vị trí mới nhất, hãy truy cập: Lớp Android LocationClient không được dùng nữa nhưng được sử dụng trong tài liệu


0

Cách đơn giản và tốt nhất cho 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();
    }

0

Ở đây hơi muộn nhưng điều tôi sẽ làm trong tình huống như vậy là sử dụng API Google Maps và đánh dấu các vị trí gần đó bằng API bản đồ dài và dài của google maps. Cộng với trải nghiệm người dùng sẽ tốt hơn nếu bạn có thể hiển thị vị trí của anh ấy / cô ấy trên bản đồ. Không cần bận tâm về việc cập nhật vị trí người dùng hoặc chạy nhanh với api android. Hãy để google maps xử lý các phần bên trong cho bạn.

@emmby có thể đã giải quyết nó trong ứng dụng của anh ấy nhưng để tham khảo trong tương lai, hãy xem API Google maps cho các công cụ cụ thể về vị trí là những gì tôi đề xuất cho các nhà phát triển đồng nghiệp.

Chỉnh sửa: Liên kết để hiển thị vị trí người dùng trong google maps


0

Nó đòi hỏi rất nhiều thứ để có được các bản cập nhật vị trí trong Android, đòi hỏi rất nhiều mã bolierplate.

Bạn cần phải chăm sóc

  • Dịch vụ Google Play có sẵn Kiểm tra,
  • Cập nhật Dịch vụ Google play nếu nó cũ hoặc không khả dụng
  • Tạo hộp thoại Tạo GoogleApiClient và các cuộc gọi lại được kết nối, ngắt kết nối, v.v.
  • Dừng và phát hành tài nguyên để cập nhật vị trí
  • Xử lý các tình huống cho phép Địa điểm
  • Kiểm tra dịch vụ vị trí đang bật hoặc tắt
  • Nhận được vị trí cuối cùng cũng không dễ dàng
  • Dự phòng vị trí đã biết cuối cùng nếu không nhận được vị trí sau thời gian nhất định

Tôi đã tạo Android-EasyLocation (thư viện Android nhỏ) sẽ chăm sóc tất cả những thứ này và bạn có thể tập trung vào logic kinh doanh.

Tất cả bạn cần là mở rộng EasyLocationActivity và điều này

requestSingleLocationFix(easyLocationRequest);

hoặc là

requestLocationUpdates(easyLocationRequest);

Thanh toán ứng dụng mẫu và các bước cần thiết tại đây tại https://github.com/akhgupta/Android- EasyLocation


0

Đây là những gì tôi làm:

  1. Trước hết tôi kiểm tra xem nhà cung cấp NETWORK hoặc GPS có được bật hay không. Một số có thể bị vô hiệu hóa trên thiết bị, một số có thể bị vô hiệu hóa trong bảng kê khai ứng dụng. Nếu bất kỳ nhà cung cấp nào được bật, tôi sẽ tìm nạp vị trí cuối cùng được lưu trong bộ nhớ cache cho nhà cung cấp này và bắt đầu trình nghe cập nhật vị trí cho nhà cung cấp này.
  2. Có một phương pháp để xác định xem một vị trí có tốt hơn vị trí nhận được cuối cùng như được đề cập trong liên kết hay không: - https://developer.android.com/guide/topics/location/strargeties.html#BestEstimate
  3. Nếu tôi nhận được cập nhật từ trình nghe vị trí, tôi sẽ kiểm tra xem vị trí này có tốt hơn vị trí nhận được trước đó không. và Nếu tốt hơn là thay thế vị trí này thành vị trí tốt nhất trước đó ( mFinalLocation).
  4. Ngoài ra còn có một trình xử lý (bộ đếm thời gian) trong hai phút, cuối cùng dừng dịch vụ và trong onDestroy()phương thức dịch vụ, ngừng lắng nghe cập nhật vị trí cho mỗi nhà cung cấp.

Dưới đây là mã cho dịch vụ. Bạn có thể chạy nó dựa trên tần suất cập nhật vị trí bạn cần.

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

0

Phiên bản Kotlin của @Fedor Greate trả lời:

sử dụng lớp học:

val locationResult = object : MyLocation.LocationResult() {

    override fun gotLocation(location: Location?) {

        val lat = location!!.latitude
        val lon = location.longitude

        Toast.makeText(context, "$lat --SLocRes-- $lon", Toast.LENGTH_SHORT).show()
    }

}

val myLocation = MyLocation()
myLocation.getLocation(inflater.context, locationResult)

MyLocation Lớp học :

class MyLocation {
    internal lateinit var timer1: Timer
    internal var lm: LocationManager? = null
    internal lateinit var locationResult: LocationResult
    internal var gps_enabled = false
    internal var network_enabled = false

    internal var locationListenerGps: LocationListener = object : LocationListener {


        override fun onLocationChanged(location: Location) {
            timer1.cancel()
            locationResult.gotLocation(location)
            lm!!.removeUpdates(this)
            lm!!.removeUpdates(locationListenerNetwork)
        }

        override fun onProviderDisabled(provider: String) {}
        override fun onProviderEnabled(provider: String) {}
        override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
    }

    internal var locationListenerNetwork: LocationListener = object : LocationListener {
        override fun onLocationChanged(location: Location) {
            timer1.cancel()
            locationResult.gotLocation(location)
            lm!!.removeUpdates(this)
            lm!!.removeUpdates(locationListenerGps)
        }

        override fun onProviderDisabled(provider: String) {}
        override fun onProviderEnabled(provider: String) {}
        override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
    }

    fun getLocation(context: Context, result: LocationResult): Boolean {
        //I use LocationResult callback class to pass location value from MyLocation to user code.
        locationResult = result
        if (lm == null)
            lm = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager?

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

        try {
            network_enabled = lm!!.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
        } catch (ex: Exception) {
        }

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

        if (ActivityCompat.checkSelfPermission(context,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
            ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) run {

            ActivityCompat.requestPermissions(context as Activity,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), 111)
        }


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

    internal inner class GetLastLocation(var context: Context) : TimerTask() {
        override fun run() {
            lm!!.removeUpdates(locationListenerGps)
            lm!!.removeUpdates(locationListenerNetwork)

            var net_loc: Location? = null
            var gps_loc: Location? = null

            if (ActivityCompat.checkSelfPermission(context,
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
            ) run {

                ActivityCompat.requestPermissions(context as Activity,
                    arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION),111)
            }


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

     abstract class LocationResult {
          abstract fun gotLocation(location: Location?)
    }
}

0

Trong lớp Activity tạo một phương thức tùy chỉnh:

private void getTheUserPermission() {
        ActivityCompat.requestPermissions(this, new String[]
                {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        LocationGetter locationGetter = new LocationGetter(FreshMenuSearchActivity.this, REQUEST_LOCATION, locationManager);


        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {

            locationGetter.OnGPS();
        } else {

            locationGetter.getLocation();
        }
    }

Tạo một tên lớp xác định người dùng LocationGetter: -

public class LocationGetter {

        private int REQUEST_LOCATION;
        private FreshMenuSearchActivity mContext;
        private LocationManager locationManager;
        private Geocoder geocoder;

        public LocationGetter(FreshMenuSearchActivity mContext, int requestLocation, LocationManager locationManager) {
            this.mContext = mContext;
            this.locationManager = locationManager;
            this.REQUEST_LOCATION = requestLocation;
        }


        public void getLocation() {

            if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,

                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(mContext, new String[]
                        {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
            } else {
                Location LocationGps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                Location LocationNetwork = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                Location LocationPassive = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);

                if (LocationGps != null) {
                    double lat = LocationGps.getLatitude();
                    double longi = LocationGps.getLongitude();
                    getTheAddress(lat, longi);
                } else if (LocationNetwork != null) {
                    double lat = LocationNetwork.getLatitude();
                    double longi = LocationNetwork.getLongitude();
                    getTheAddress(lat, longi);
                } else if (LocationPassive != null) {
                    double lat = LocationPassive.getLatitude();
                    double longi = LocationPassive.getLongitude();
                    getTheAddress(lat, longi);
                } else {
                    Toast.makeText(mContext, "Can't Get Your Location", Toast.LENGTH_SHORT).show();
                }

            }

        }

        private void getTheAddress(double latitude, double longitude) {
            List<Address> addresses;
            geocoder = new Geocoder(mContext, Locale.getDefault());

            try {
                addresses = geocoder.getFromLocation(latitude, longitude, 1);
                String address = addresses.get(0).getAddressLine(0);
                String city = addresses.get(0).getLocality();
                String state = addresses.get(0).getAdminArea();
                String country = addresses.get(0).getCountryName();
                String postalCode = addresses.get(0).getPostalCode();
                String knownName = addresses.get(0).getFeatureName();
                Log.d("neel", address);
            } catch (IOException e) {
                e.printStackTrace();
            }


        }

        public void OnGPS() {

            final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);

            builder.setMessage("Enable GPS").setCancelable(false).setPositiveButton("YES", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    mContext.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                }
            }).setNegativeButton("NO", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                    dialog.cancel();
                }
            });
            final AlertDialog alertDialog = builder.create();
            alertDialog.show();
        }

    }

Làm cách nào để bật GPS chỉ bằng cách nhấp vào "CÓ" thay vì chuyển hướng người dùng đến cấu hình?
Aliton Oliveira

khi bạn nhấp vào nút có: mContext.startActivity (ý định mới (Cài đặt.ACTION_LOCATION_SOURCE_SETTINGS)); ý định rõ ràng sẽ bị sa thải để kích hoạt GPS. @AlitonOliveira
neelkanth_vyas

-1

Bằng cách sử dụng FuseLocationProviderApi, đây là API mới nhất và tốt nhất trong số các khả năng có sẵn để có được vị trí trong Android. thêm phần này vào tập tin build.gradle

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

bạn có thể nhận được mã nguồn đầy đủ bằng url này http://javapapers.com/android/android-location-fuse-provider/


-1

Gần đây được tái cấu trúc để có được vị trí của mã, tìm hiểu một số ý tưởng hay và cuối cùng đã đạt được một thư viện và Demo tương đối hoàn hảo.

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

Mã hoàn chỉnh: https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java

* Mỗi yêu cầu hoàn thành vị trí, tốt nhất là xóaUpdates, nếu không, thanh trạng thái điện thoại sẽ luôn hiển thị biểu tượng định vị.


-1

Sau khi xem tất cả các câu trả lời, và câu hỏi ( Đơn giản và mạnh mẽ nhất ). Tôi đã nhấp vào chỉ thư viện Android-ReactiveLocation .

Khi tôi thực hiện một ứng dụng theo dõi vị trí. Sau đó, tôi nhận ra rằng nó rất điển hình để xử lý theo dõi vị trí với tối ưu hóa với pin.

Vì vậy, tôi muốn nói với những người mới và cả những nhà phát triển không muốn duy trì mã vị trí của họ với những tối ưu hóa trong tương lai. Sử dụng thư viện này.

ReactiveLocationProvider locationProvider = new 

    ReactiveLocationProvider(context);
    locationProvider.getLastKnownLocation()
        .subscribe(new Consumer<Location>() {
            @Override
            public void call(Location location) {
                doSthImportantWithObtainedLocation(location);
            }
        });

Phụ thuộc để đưa vào xây dựng cấp độ ứng dụng.

dependencies {
    ...
    compile 'pl.charmas.android:android-reactive-location2:2.1@aar'
    compile 'com.google.android.gms:play-services-location:11.0.4' //you can use newer GMS version if you need
    compile 'com.google.android.gms:play-services-places:11.0.4'
    compile 'io.reactivex:rxjava:2.0.5' //you can override RxJava version if you need
}

Ưu điểm khi sử dụng lib này:

  • Lib này đang và sẽ được duy trì tích cực.
  • Bạn không lo lắng về tối ưu hóa pin. Khi các nhà phát triển đã làm hết sức mình.
  • Dễ dàng cài đặt, đặt phụ thuộc và chơi.
  • dễ dàng kết nối với API dịch vụ Play
  • có được vị trí cuối cùng được biết đến
  • đăng ký để sử dụng cập nhật vị trí
  • API cài đặt vị trí
  • quản lý địa chất
  • vị trí mã địa lý để liệt kê các địa chỉ
  • công nhận hoạt động
  • sử dụng địa điểm tìm nạp API hiện tại
  • đề xuất tự động hoàn thành
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.