วิธีที่ง่ายและแข็งแกร่งที่สุดในการรับตำแหน่งปัจจุบันของผู้ใช้บน Android คืออะไร


811

LocationManagerAPI บน Android ดูเหมือนว่ามันเป็นบิตของความเจ็บปวดที่จะใช้สำหรับโปรแกรมที่ต้องการเพียงการประมาณครั้งคราวและหยาบของตำแหน่งของผู้ใช้ด้วย

แอพที่ฉันใช้งานอยู่ไม่ใช่แอปที่ตั้งจริง ๆ แต่มันต้องได้รับตำแหน่งของผู้ใช้เพื่อแสดงรายการธุรกิจใกล้เคียง ไม่จำเป็นต้องกังวลหากผู้ใช้มีการเคลื่อนไหวหรืออะไรทำนองนั้น

นี่คือสิ่งที่ฉันต้องการจะทำ:

  1. แสดงรายชื่อผู้ใช้ของสถานที่ใกล้เคียง
  2. โหลดตำแหน่งของผู้ใช้ล่วงหน้าเพื่อให้ตามเวลาที่ฉันต้องการในActivityX จะสามารถใช้งานได้
  3. ฉันไม่สนใจเกี่ยวกับความแม่นยำหรือความถี่ของการอัปเดตเป็นพิเศษ เพียงแค่คว้าตำแหน่งเดียวก็เพียงพอตราบเท่าที่ยังไม่ได้ออก บางทีถ้าฉันต้องการแฟนซีฉันจะอัปเดตตำแหน่งทุกๆสองสามนาทีหรือมากกว่านั้น แต่มันก็ไม่ได้สำคัญอะไรมาก
  4. ทำงานกับอุปกรณ์ใดก็ได้ตราบใดที่มี GPS หรือผู้ให้บริการตำแหน่งเครือข่าย

ดูเหมือนว่ามันไม่ควรจะยากขนาดนั้น แต่สำหรับฉันแล้วฉันต้องหมุนผู้ให้บริการตำแหน่งสองแห่ง (GPS และ NETWORK) และจัดการวงจรชีวิตของแต่ละคน ไม่เพียงแค่นั้น แต่ฉันต้องทำซ้ำรหัสเดียวกันในหลายกิจกรรมเพื่อให้เป็นไปตาม # 2 ฉันเคยลองใช้getBestProvider()ในอดีตเพื่อลดโซลูชันลงเพียงแค่ใช้ผู้ให้บริการตำแหน่งรายเดียว แต่ดูเหมือนจะให้เฉพาะผู้ให้บริการ "เชิงทฤษฎี" ที่ดีที่สุดมากกว่าผู้ให้บริการที่จะให้ผลลัพธ์ที่ดีที่สุดแก่คุณ

มีวิธีที่ง่ายกว่าในการทำสิ่งนี้หรือไม่?


5
ที่นี่คุณสามารถค้นหาบทช่วยสอนทีละขั้นตอนพร้อมโค้ดตัวอย่างสำหรับ GPS ไชโย !!
swiftBoy

1
คุณสามารถใช้ห้องสมุดง่าย ๆ ที่สรุปสิ่งต่าง ๆ ที่ต้องเกิดขึ้น "ภายใต้ประทุน": github.com/delight-im/Android-SimpleLocation
caw

ในปี 2561 เป็นตัวอย่าง FusedLocationProviderClient สำหรับการอัปเดตตำแหน่งพื้นหลังfreakyjolly.com/…
รหัส Spy

รับคำตอบใน Kotlin ได้ที่นี่: stackoverflow.com/a/53800632/2201814
MHSFisher

คุณสามารถใช้เทคนิคการถ่ายภาพสถานที่หลอมรวมใน Android
SIVAKUMAR.J

คำตอบ:


946

นี่คือสิ่งที่ฉันทำ:

  1. ก่อนอื่นฉันตรวจสอบว่าผู้ให้บริการรายใดเปิดใช้งาน บางส่วนอาจถูกปิดการใช้งานบนอุปกรณ์บางอย่างอาจถูกปิดใช้งานในรายการแอปพลิเคชัน
  2. หากผู้ให้บริการรายใดว่างฉันเริ่มฟังตำแหน่งและตัวจับเวลาหมดเวลา ในตัวอย่างของฉัน 20 วินาทีอาจไม่เพียงพอสำหรับ GPS เพื่อให้คุณสามารถขยายได้
  3. หากฉันได้รับการอัปเดตจากผู้ฟังตำแหน่งฉันจะใช้ค่าที่ให้ไว้ ฉันหยุดฟังและจับเวลา
  4. หากฉันไม่ได้รับการอัปเดตและตัวจับเวลาใด ๆ ฉันต้องใช้ค่าที่ทราบล่าสุด
  5. ฉันคว้าค่าล่าสุดที่ทราบจากผู้ให้บริการที่มีอยู่และเลือกล่าสุดของพวกเขา

นี่คือวิธีที่ฉันใช้คลาส:

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

และนี่คือคลาส MyLocation:

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

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

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

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

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

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

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

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

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

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

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

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

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

บางคนอาจต้องการปรับเปลี่ยนตรรกะของฉัน ตัวอย่างเช่นหากคุณได้รับการอัปเดตจากผู้ให้บริการเครือข่ายจะไม่หยุดฟัง แต่รอต่อไป GPS ให้ข้อมูลที่แม่นยำยิ่งขึ้นดังนั้นมันจึงคุ้มค่าที่จะรอ หากตัวจับเวลาผ่านไปและคุณได้รับการอัปเดตจากเครือข่าย แต่ไม่ใช่จาก GPS คุณสามารถใช้ค่าที่ได้รับจากเครือข่าย

วิธีการหนึ่งที่มากขึ้นคือการใช้ LocationClient http://developer.android.com/training/location/retrieve-current.html แต่จะต้องติดตั้ง Google Play Services apk บนอุปกรณ์ของผู้ใช้


7
สำหรับบันทึกความเข้าใจของฉันก็คือโดยทั่วไปแล้ว Google แนะนำให้ใช้ android: configChanges แต่ฉันกลับไปพร้อมกับวิธีแก้ปัญหาที่ลงทะเบียน timertasks และยกเลิกพวกเขาในการทำลาย
emmby

5
ใช้คลาสนี้ในแอพเรียบง่ายของฉันและใช้งานได้เหมือนแชมป์ ขอบคุณสำหรับการโพสต์!
Alex Pritchard

46
มันใช้งานได้ดีสำหรับฉัน! อย่างไรก็ตามกิจกรรมที่ฉันใช้สิ่งนี้สำหรับฉันจะตรวจสอบตำแหน่งในประวัติย่อ หากผู้ใช้ออกจากกิจกรรมก่อนที่จะส่งคืนตำแหน่งแอปพลิเคชันจะล้มเหลว ฉันแก้ไขได้โดยการเพิ่มวิธีนี้ใน MyLocation class.public ของคุณเป็นโมฆะ cancelTimer () {timer1.cancel (); lm.removeUpdates (locationListenerGps); lm.removeUpdates (locationListenerNetwork); } ฉันเรียกสิ่งนี้ว่า onPause () และนั่นเป็นการแก้ไขความผิดพลาด
dbaugh

14
สวัสดีฉันสามารถใช้รหัสของคุณในใบสมัครเพื่อการค้า หากคุณมีข้อร้องเรียนใด ๆ เกี่ยวกับเรื่องนั้นโปรดแจ้งให้เราทราบ
TRonZ

87
@TRonZ ไม่มีปัญหากรุณาใช้มันเพื่อวัตถุประสงค์ใด ๆ
Fedor

43

หลังจากค้นหาการนำไปใช้ที่ดีที่สุดวิธีรับตำแหน่งผู้ใช้ที่แม่นยำที่สุดฉันจัดการเพื่อรวมวิธีการที่ดีที่สุดทั้งหมดและมากับคลาสต่อไปนี้:

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

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

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

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

    private boolean gps_enabled = false;

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

    private Runnable showTime = new Runnable() {

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

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

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

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

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

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

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

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

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

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

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

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

        bestLocation = null;
        counts = 0;

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

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

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

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

                     sat_count = 0;

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

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

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

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

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

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


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

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

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

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

คลาสนี้พยายามเชื่อมต่อกับmin_gps_sat_countดาวเทียมหากเปิดใช้งาน GPS อื่นจะส่งคืนLocationManager.getBestProvider()ตำแหน่ง ตรวจสอบรหัส!


2
จะหยุดหลังจาก 1 นาทีหรือเมื่อพบตำแหน่ง
Wormhit

@wormhit ในกรณีของฉันมันไม่หยุดหลังจากนับ 120 ฉันเปิดใช้งาน GPS และผู้ให้บริการเครือข่ายแล้วฉันยังได้เพิ่มสิทธิ์ที่เหมาะสมในไฟล์ Menifest
Narendra Pal

เพียงแค่ใส่สิ่งเหล่านี้เป็นการนำเข้า: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;
แจ็กกี้ชาน

31

ด้วยโซลูชันของ Fedor ฉันมีประสบการณ์ในการโทรกลับgotLocationหลายครั้ง มันน่าจะเป็นเนื่องจากมีสภาพการแข่งขันในแทนที่LocationListener.onLocationChangedวิธีการเมื่อวิธีการ gotLocation เป็น'นานพอ' ฉันไม่แน่ใจ แต่ฉันเดาremoveUpdatesจะป้องกันการจัดคิวข้อความใหม่ในคิว Looper แต่มันไม่ได้ลบข้อความที่เข้าคิวแล้ว แต่ยังไม่หมดไป ดังนั้นสภาพการแข่งขัน

เพื่อลดความน่าจะเป็นของพฤติกรรมที่ไม่ถูกต้องนี้เป็นไปได้ที่จะเรียก removeUpdates ก่อนที่จะยิงเหตุการณ์ onLocationChanged แต่เรายังมีสภาพการแข่งขันอยู่

ทางออกที่ดีที่สุดที่ฉันพบคือการแทนที่requestLocationUpdatesด้วยrequestSingleUpdateด้วย

นี่คือรุ่นของฉันตามโซลูชันของ Fedor โดยใช้ตัวจัดการเพื่อส่งข้อความไปยังเธรด looper:

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

ฉันใช้คลาสนี้จากเธรด Looper ที่กำหนดเองเช่นเดียวกับต่อไปนี้:

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

โดยที่ Coordinates เป็นคลาสง่าย ๆ ที่มีคุณสมบัติสองอย่างคือละติจูดและลองจิจูด


4
ประเด็นที่น่าสนใจก็คือ RequestSingleUpdate ต้องการระดับ API 9 แต่ +1 สำหรับการชี้ให้เห็น
Eduardo

@Eduardo: ความเป็นไปได้อีกประการหนึ่งคือการเรียกใช้โค้ดของงานโดยใช้ Handler ที่เกี่ยวข้องกับ looper และเรียกมันโดยการส่งข้อความ (ว่าง) ไปยังตัวจัดการ เนื่องจากข้อความได้รับการจัดลำดับในคิว Looper คุณสามารถลบด้วยตนเอง (เช่นการใช้แฟล็ก) สภาวะการแข่งขัน ไม่จำเป็นต้องใช้ API Livel 9 แต่ต้องใช้ looper อย่างชัดเจน
differenziale

17

ฉันได้สร้างแอปพลิเคชันขนาดเล็กพร้อมคำอธิบายทีละขั้นตอนเพื่อให้ได้ตำแหน่งปัจจุบันพิกัด GPS

ป้อนคำอธิบายรูปภาพที่นี่

กรอกซอร์สโค้ดตัวอย่างใน URL ด้านล่าง:


รับพิกัดตำแหน่งปัจจุบันชื่อเมือง - ใน Android


ดูว่ามันทำงานอย่างไร:

  • สิ่งที่เราต้องทำคือเพิ่มการอนุญาตนี้ในไฟล์ Manifest

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">  
    </uses-permission>
  • และสร้างอินสแตนซ์ LocationManager เช่นนี้

    LocationManager locationManager = (LocationManager) 
                                      getSystemService(Context.LOCATION_SERVICE);
  • ตรวจสอบว่ามีการเปิดใช้งาน GPS หรือไม่

  • จากนั้นใช้ LocationListener และรับพิกัด

    LocationListener locationListener = new MyLocationListener();  
    locationManager.requestLocationUpdates(  
    LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
  • นี่คือตัวอย่างโค้ดที่ต้องทำ


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

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

    @Override
    public void onProviderDisabled(String provider) {}

    @Override
    public void onProviderEnabled(String provider) {}

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

1
สถานที่จะต้องมีการเปลี่ยนแปลง ไม่ในขณะที่ยืน

15

คุณสามารถใช้LocationManager.getLastKnownLocation ()ได้ตลอดเวลาแต่อย่างที่บอกว่ามันล้าสมัย

และวิธีง่ายๆในการรับตำแหน่งทั่วไปสามารถลงทะเบียนสำหรับเครือข่าย (ปกติจะค่อนข้างเร็ว)

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

แล้วทำ

locationManager.removeUpdates(this);

ในonLocationChanged()วิธีการฟัง


ขอบคุณ BrennaSoft ฉันพบว่า getLastKnownLocation () สามารถปิดได้บ่อยและดังนั้นจึงไม่ได้ทำงานเป็นโซลูชันแบบสแตนด์อโลน นอกจากนี้ยังไม่ชัดเจนสำหรับฉันว่าการใช้ NETWORK_PROVIDER เพียงอย่างเดียวจะทำงานได้เนื่องจากหลายพื้นที่ของประเทศไม่มีพิกัด GPS ที่ดีมากสำหรับจุดเชื่อมต่อ wifi (และฉันไม่รู้เกี่ยวกับเสาสัญญาณโทรศัพท์)
emmby

9

ฉันได้เขียนแบบฝึกหัดที่มีรายละเอียดครอบคลุมตำแหน่งปัจจุบันที่นี่ในdemonuts.comคุณสามารถค้นหาคำอธิบายเพิ่มเติมได้ที่นี่และคุณสามารถดาวน์โหลดซอร์สโค้ดสาธิตทั้งหมดเพื่อความเข้าใจที่ดีขึ้น

มีคำตอบมากมายอยู่แล้ว แต่ฉันต้องการแสดงวิธีล่าสุดในการรับตำแหน่งโดยใช้ Google API ดังนั้นโปรแกรมเมอร์ใหม่จึงสามารถใช้วิธีการใหม่ได้:

ก่อนอื่นให้วางสิ่งนี้ลงในไฟล์ gradle

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

จากนั้นใช้อินเทอร์เฟซที่จำเป็น

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

ประกาศอินสแตนซ์

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

ใส่สิ่งนี้ใน onCreate()

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

ในที่สุดก็แทนที่วิธีที่จำเป็น

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

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

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

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

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

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

    }

อย่าลืมเริ่ม GPS ในอุปกรณ์ของคุณก่อนเปิดแอพ


ใช้ API? ดังนั้นนี่คือบริการคือ จำกัด อัตรา
user3304007

8

ที่จริงเราสามารถใช้ผู้ให้บริการสองราย (GPS & NETWORK) และพวกเขาแค่แบ่งปันผู้ฟังสาธารณะ:

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

สิ่งนี้มีความจำเป็นเนื่องจากOnLocationChanged()ต้องเรียกใช้วิธีการในเวลาเสมอ


5

ฉันไม่แน่ใจว่าLocation-Based Servicesสามารถรับตำแหน่งจากโครงสร้างพื้นฐานอื่น ๆ ที่นอกเหนือจาก GPS ได้หรือไม่ แต่จากบทความนั้นพบว่าเป็นไปได้:

แอปพลิเคชันสามารถเรียกใช้วิธีการระบุตำแหน่งหลายประเภท

การใช้เครือข่ายโทรศัพท์มือถือ: ID เซลล์ปัจจุบันสามารถใช้เพื่อระบุสถานีฐานรับส่งสัญญาณ (BTS) ที่อุปกรณ์กำลังสื่อสารด้วยและที่ตั้งของ BTS นั้น เห็นได้ชัดว่าความแม่นยำของวิธีนี้ขึ้นอยู่กับขนาดของเซลล์และอาจไม่ถูกต้องนัก เซลล์ GSM อาจมีขนาดเส้นผ่าศูนย์กลางตั้งแต่ 2 ถึง 20 กิโลเมตร เทคนิคอื่น ๆ ที่ใช้พร้อมกับ ID เซลล์สามารถบรรลุความแม่นยำภายใน 150 เมตร

การใช้ดาวเทียม: ระบบกำหนดตำแหน่งบนโลก (GPS) ซึ่งควบคุมโดยกระทรวงกลาโหมของสหรัฐอเมริกาใช้กลุ่มดาวเทียม 24 ดวงที่โคจรรอบโลก GPS กำหนดตำแหน่งของอุปกรณ์โดยการคำนวณความแตกต่างในเวลาที่สัญญาณจากดาวเทียมที่แตกต่างกันไปถึงผู้รับ สัญญาณ GPS ถูกเข้ารหัสดังนั้นอุปกรณ์มือถือจะต้องติดตั้งตัวรับสัญญาณ GPS GPS อาจเป็นวิธีที่แม่นยำที่สุด (ระหว่าง 4 ถึง 40 เมตรหากตัวรับสัญญาณ GPS มีมุมมองที่ชัดเจนของท้องฟ้า) แต่มีข้อบกพร่องบางอย่าง: ฮาร์ดแวร์เพิ่มเติมอาจมีราคาแพงใช้แบตเตอรี่ในขณะที่ใช้งาน หลังจากเริ่มเย็นเพื่อรับการแก้ไขเริ่มต้นบนดาวเทียมที่มองเห็น นอกจากนี้ยังได้รับผลกระทบจาก "แคนยอนเอฟเฟกต์" ในเมืองที่การมองเห็นดาวเทียมนั้นไม่สม่ำเสมอ

การใช้บีคอนการระบุตำแหน่งระยะสั้น: ในพื้นที่ที่มีขนาดค่อนข้างเล็กเช่นอาคารเดียวเครือข่ายท้องถิ่นสามารถให้บริการตำแหน่งพร้อมกับบริการอื่น ๆ ตัวอย่างเช่นอุปกรณ์ที่มีอุปกรณ์อย่างเหมาะสมสามารถใช้บลูทู ธ สำหรับการจัดตำแหน่งระยะสั้น


1
@ElijahSaounkine เห็นได้ชัดว่า npinti ไม่เคยได้ยิน Assisted GPS ในอนาคตคุณอาจเพียงแค่แจ้งให้ผู้คนในสิ่งที่พวกเขาได้ดูแลแทนการก้าวร้าวเกี่ยวกับเรื่องนี้
saltandpepper

@ Sammy 5 ปีที่ผ่านมาดูเหมือนว่าฉันจะกระโดดได้มากขึ้นกว่านี้ "อนาคต" ที่คุณอ้างถึงซึ่งเกี่ยวข้องกับบันทึกของฉันอาจจะเริ่มต้นและสิ้นสุดแล้ว)
Elijah Saounkine

5

ใช้รหัสด้านล่างมันจะให้บริการที่ดีที่สุด:

String locCtx = Context.LOCATION_SERVICE; 

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

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

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

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

วิธีการเริ่มต้น ctx บริบท ctx = นี้; ? มันล้มเหลว

4

วิธีที่แนะนำให้ทำคือใช้LocationClient:

ก่อนอื่นให้กำหนดค่าช่วงเวลาการอัพเดทตำแหน่ง ปรับให้เหมาะกับความต้องการของคุณ

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

มีของActivityใช้GooglePlayServicesClient.ConnectionCallbacks, และGooglePlayServicesClient.OnConnectionFailedListenerLocationListener

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

จากนั้นตั้งค่า a LocationClientในonCreate()วิธีการของคุณActivity:

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

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

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

เพิ่มวิธีการที่จำเป็นให้กับคุณActivity; onConnected()เป็นวิธีการที่เรียกว่าเมื่อLocationClientเชื่อมต่อ onLocationChanged()เป็นที่ที่คุณจะเรียกคืนตำแหน่งล่าสุด

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

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

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

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

ตรวจสอบให้แน่ใจว่าได้เชื่อมต่อ / ยกเลิกการเชื่อมต่อLocationClientดังนั้นจึงใช้แบตเตอรี่เสริมเมื่อจำเป็นเท่านั้นและ GPS จะไม่ทำงานอย่างไม่มีกำหนด LocationClientต้องเชื่อมต่อเพื่อให้ได้รับข้อมูลจากมัน

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

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

รับตำแหน่งของผู้ใช้ ก่อนอื่นให้ลองใช้LocationClient; LocationManagerหากที่ล้มเหลวถอยกลับไป

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

3

แม้ว่าคำตอบจะได้รับที่นี่แล้ว ฉันแค่อยากจะแบ่งปันสิ่งนี้กับคนทั่วโลกในกรณีที่เจอสถานการณ์แบบนั้น

ความต้องการของฉันคือการที่ฉันต้องการที่จะได้รับตำแหน่งปัจจุบันของผู้ใช้ภายใน 30-35 วินาทีที่สูงสุดเพื่อให้ที่นี่เป็นวิธีการแก้ฉันทำต่อไปนี้คำตอบ Nirav Ranpara ของ

1.ฉันสร้างคลาสMyLocationManager.javaซึ่งจัดการข้อมูล GPS และเครือข่ายทั้งหมด

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

import com.app.callbacks.OnLocationDetectectionListener;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        }

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

        }

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

        }

        @Override
        public void onLocationChanged(Location location) {

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

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

        }

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

        }

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

        }

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

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

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

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

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

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

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

2.ฉันสร้างอินเทอร์เฟซ (โทรกลับ) OnLocationDetectectionListener.javaเพื่อสื่อสารผลลัพธ์กลับไปยังส่วนการโทรหรือกิจกรรม

import android.location.Location;

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

3.จากนั้นฉันสร้างMainAppActivty.java Activity ที่ใช้OnLocationDetectectionListenerส่วนต่อประสานและนี่คือวิธีที่ฉันรับตำแหน่งของฉัน

public class MainAppActivty extends Activity implements
        OnLocationDetectectionListener {

    private Location currentLocation;
    private MyLocationManager mLocationManager;

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

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

4.เพิ่มสิทธิ์ต่อไปนี้ในไฟล์ Manifest ของคุณ

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

หวังว่านี่จะเป็นประโยชน์กับคนอื่น ๆ :)


3

จากล่าสุดมากกว่าหนึ่งปีฉันใช้ GPS_PROVIDER และ NETWORK_PROVIDER เพื่อรับตำแหน่งปัจจุบันและใช้งานได้ดี แต่จากไม่กี่เดือนที่ผ่านมาฉันได้รับตำแหน่งหลังจากล่าช้าเป็นเวลานานดังนั้นฉันจึงเปลี่ยนเป็น API FusedLocationProviderClient ล่าสุดและ มันใช้งานได้ดีทีเดียว

นี่คือคลาสที่ฉันเขียนเพื่อรับตำแหน่งปัจจุบันโดยใช้ FusedLocationProviderClient ในโค้ดด้านล่างฉันใช้ตัวจับเวลาเพื่อรอขณะรับตำแหน่งปัจจุบันฉันตั้งเวลาหน่วงเวลา 15 วินาทีคุณสามารถเปลี่ยนได้ตามที่คุณต้องการ

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

และเรียกสิ่งนี้จากกิจกรรมนี่คือรหัส

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

เพิ่มรายการต่อไปนี้ใน 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

นี่คือรหัสที่ให้ตำแหน่งปัจจุบันของผู้ใช้

สร้าง Maps Activty:

public class Maps extends MapActivity {

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

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

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

            public void onProviderEnabled(String arg0) {}

            public void onProviderDisabled(String arg0) {}

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

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

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

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

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

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

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

    class MapOverlay extends Overlay {

        private GeoPoint pointToDraw;

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

        public GeoPoint getPointToDraw() {
            return pointToDraw;
        }

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

main.xml:

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

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

    </LinearLayout>

และกำหนดสิทธิ์ต่อไปนี้ในรายการ:

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

2

นี่คือวิธีที่ฉันร้องขอสิทธิ์ผู้ใช้

นอกแท็กแอปพลิเคชันของคุณใน AndroidManifest.xml เพิ่มคำขอสิทธิ์เหล่านี้

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

จากนั้นเพิ่มการอ้างอิงตำแหน่งของ Google ในไฟล์ App Gradle

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

ตอนนี้ประกาศตัวแปรทั่วโลก

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

ในวิธี OnCreate ของกิจกรรมของคุณ (ฉันไม่สามารถจัดรูปแบบโค้ดอย่างถูกต้องขอโทษสำหรับสิ่งนั้น)

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

ตอนนี้สร้างฟังก์ชั่นทั้งสอง

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

    }

วิธีที่สอง

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

สำหรับ 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

การปรับปรุงโซลูชันของ @ Fedor แทนที่จะขอตำแหน่งด้วยช่วงเวลา '0' และระยะทาง '0' เราสามารถใช้เมธอดRequestSingleUpdateของผู้จัดการสถานที่ได้ อัปเดตรหัส (เวอร์ชั่น 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?)
  }
}

ในการรับตำแหน่งต้องเรียกเมธอด getLocation ตาม -

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

หมายเหตุ: ก่อนที่จะเรียกใช้เมธอด getLocation ต้องได้รับอนุญาตจากตำแหน่งที่กำหนด


1

MyLocationOverlayจะได้รับและแสดงตำแหน่งปัจจุบันของผู้ใช้นอกจากนี้คุณยังสามารถใช้ สมมติว่าคุณมีmapViewฟิลด์ในกิจกรรมของคุณ สิ่งที่คุณต้องทำเพื่อแสดงตำแหน่งผู้ใช้มีดังต่อไปนี้:

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

สิ่งนี้ได้รับตำแหน่งปัจจุบันจากทั้ง GPS หรือเครือข่าย หากทั้งสองล้มเหลวจะกลับมาenableMyLocation()false

สำหรับสถานที่ตั้งของสิ่งต่าง ๆ รอบ ๆ พื้นที่ItemizedOverlayควรทำเคล็ดลับ

ฉันหวังว่าฉันจะไม่เข้าใจคำถามของคุณผิด โชคดี.


2
ขอบคุณ. คำถามสำหรับกิจกรรมที่ไม่มีมุมมองแผนที่และไม่จำเป็นต้องแสดงตำแหน่งให้ผู้ใช้เห็น
emmby

1

แก้ไข: อัปเดตด้วยAPI บริการตำแหน่งล่าสุดจากห้องสมุด Google Play Services (กรกฎาคม 2014)

ฉันอยากจะแนะนำให้คุณใช้Location Service API ใหม่มีอยู่ในห้องสมุด Google Play Services ซึ่งให้กรอบที่มีประสิทธิภาพและระดับสูงที่ทำงานอัตโนมัติเช่นตัวเลือกผู้ให้บริการตำแหน่งและการจัดการพลังงาน ตามเอกสารอย่างเป็นทางการ: "... API ของที่อยู่ทำให้คุณสามารถสร้างแอปพลิเคชันที่ทราบตำแหน่งได้โดยไม่จำเป็นต้องให้ความสำคัญกับรายละเอียดของเทคโนโลยีตำแหน่งพื้นฐานนอกจากนี้ยังช่วยให้คุณลดการใช้พลังงานโดยใช้ความสามารถทั้งหมด ของฮาร์ดแวร์อุปกรณ์ "

สำหรับการเยี่ยมชมข้อมูลเพิ่มเติม: การทำให้แอปของคุณรับรู้ตำแหน่ง

หากต้องการดูตัวอย่างแบบเต็มโดยใช้การเยี่ยมชม API การบริการตำแหน่งล่าสุด: คลาส Android LocationClient เลิกใช้แล้ว แต่ใช้ในเอกสารประกอบ


0

วิธีที่ง่ายและดีที่สุดสำหรับ 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

สายไปหน่อย แต่สิ่งที่ฉันจะทำในสถานการณ์เช่นนี้คือการใช้ Google Maps API และทำเครื่องหมายสถานที่ใกล้เคียงโดยใช้ lat และ API แบบยาวของ google maps ประสบการณ์การใช้งานที่ดียิ่งขึ้นถ้าคุณสามารถแสดงตำแหน่งของเขา / เธอบนแผนที่ ไม่จำเป็นต้องกังวลเกี่ยวกับการอัปเดตตำแหน่งของผู้ใช้หรือ frisking กับ Android API ให้แผนที่ google จัดการ internals ให้คุณ

@emmby อาจจะได้รับการแก้ไขในแอปของเขา แต่สำหรับการอ้างอิงในอนาคตให้ดูที่ Google Maps API สำหรับข้อมูลเฉพาะสถานที่เป็นสิ่งที่ฉันแนะนำให้เพื่อนนักพัฒนา

แก้ไข: ลิงก์สำหรับแสดงตำแหน่งผู้ใช้ใน Google แผนที่


0

ต้องมีหลายสิ่งในการรับการอัปเดตตำแหน่งใน android ต้องใช้รหัส bolierplate มากมาย

คุณต้องดูแล

  • บริการตรวจสอบความพร้อมใช้งานของ Google Play
  • อัปเดตบริการ Google play หากเป็นรุ่นเก่าหรือใช้งานไม่ได้
  • กล่องโต้ตอบการสร้าง GoogleApiClient และการโทรกลับที่เชื่อมต่อถูกตัดการเชื่อมต่อ ฯลฯ
  • การหยุดและปล่อยทรัพยากรสำหรับการอัปเดตตำแหน่ง
  • การจัดการสถานการณ์การอนุญาตสถานที่
  • การตรวจสอบบริการระบุตำแหน่งเป็นเปิดหรือปิด
  • การหาที่ตั้งล่าสุดไม่ใช่เรื่องง่าย
  • ย้อนกลับไปยังตำแหน่งที่รู้จักล่าสุดหากไม่ได้รับตำแหน่งหลังจากระยะเวลาหนึ่ง

ฉันได้สร้างAndroid-EasyLocation (ห้องสมุด android ขนาดเล็ก)ซึ่งจะดูแลทุกสิ่งนี้และคุณสามารถมุ่งเน้นไปที่ตรรกะทางธุรกิจ

สิ่งที่คุณต้องการคือขยายEasyLocationActivityและสิ่งนี้

requestSingleLocationFix(easyLocationRequest);

หรือ

requestLocationUpdates(easyLocationRequest);

ชำระเงินแอปตัวอย่างและขั้นตอนที่จำเป็นที่นี่ที่https://github.com/akhgupta/Android-EasyLocation


0

นี่คือสิ่งที่ฉันทำ:

  1. ก่อนอื่นฉันตรวจสอบว่ามีการเปิดใช้งาน NETWORK หรือ GPS หรือไม่ บางส่วนอาจถูกปิดการใช้งานบนอุปกรณ์บางอย่างอาจถูกปิดใช้งานในรายการแอปพลิเคชัน หากเปิดใช้งานผู้ให้บริการรายใดฉันจะดึงข้อมูลตำแหน่งสุดท้ายของแคชสำหรับผู้ให้บริการรายนี้และเริ่มอัปเดตตำแหน่งผู้ฟังสำหรับผู้ให้บริการนี้
  2. มีวิธีการตรวจสอบว่าสถานที่ตั้งนั้นดีกว่าสถานที่ที่ได้รับครั้งล่าสุดตามที่ระบุไว้ในลิงค์: - https://developer.android.com/guide/topics/location/strategies.html#BestEstimate
  3. หากฉันได้รับการอัปเดตจากผู้ฟังตำแหน่งฉันจะตรวจสอบว่าตำแหน่งนี้ดีกว่าตำแหน่งที่ได้รับก่อนหน้านี้หรือไม่ และหากดีกว่าแทนที่ตำแหน่งนี้เป็นตำแหน่งที่ดีที่สุดก่อนหน้า (mFinalLocation )
  4. นอกจากนี้ยังมีตัวจัดการ (ตัวจับเวลา) เป็นเวลาสองนาทีซึ่งในที่สุดก็หยุดบริการและในonDestroy()วิธีการบริการหยุดฟังการอัพเดทตำแหน่งสำหรับผู้ให้บริการแต่ละราย

ด้านล่างเป็นรหัสสำหรับบริการ คุณสามารถเรียกใช้ได้ตามความถี่ของการอัปเดตตำแหน่งที่คุณต้องการ

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


public class RecordLocationService extends Service {

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

    private final int TWO_MINUTES = 1000 * 60 * 2;

    private LocationManager mLocationManager;

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

    private Location mFinalLocation;

    private class MyLocationListener implements LocationListener {
        private String mProvider;

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

        public String getProvider() {
            return mProvider;
        }

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

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

        }

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

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

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

    private Handler mStopServiceHandler = new Handler() {

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

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

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

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

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

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

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

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

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

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

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

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

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


    }

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

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

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

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

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

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

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

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

0

รุ่น Kotlin ของ @Fedor Greateคำตอบ :

การใช้งานของชั้นเรียน:

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 คลาส:

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

ในคลาสกิจกรรมทำให้วิธีการที่กำหนดเอง:

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

สร้างชื่อคลาสที่ผู้ใช้กำหนด 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();
        }

    }

วิธีเปิดใช้งาน GPS เพียงแค่คลิกที่ "ใช่" แทนที่จะเปลี่ยนเส้นทางผู้ใช้ไปยังการกำหนดค่า
Aliton Oliveira

เมื่อคุณคลิกที่ปุ่มใช่: mContext.startActivity (เจตนาใหม่ (Settings.ACTION_LOCATION_SOURCE_SETTINGS)); เจตนาที่ชัดเจนจะถูกไล่ออกเพื่อเปิดใช้งาน GPS @AlitonOliveira
neelkanth_vyas

-1

โดยใช้ FusedLocationProviderApi ซึ่งเป็น API ล่าสุดและดีที่สุดในบรรดาความเป็นไปได้ที่จะหาตำแหน่งใน Android เพิ่มในไฟล์ build.gradle

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

คุณสามารถรับซอร์สโค้ดแบบเต็มโดย url http://javapapers.com/android/android-location-fused-provider/


-1

เมื่อไม่นานมานี้ได้รับการปรับโครงสร้างใหม่เพื่อให้ได้ตำแหน่งของโค้ดเรียนรู้แนวคิดที่ดีและในที่สุดก็ประสบความสำเร็จในการสร้างไลบรารี่และการสาธิตที่สมบูรณ์แบบ

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

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


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

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

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

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

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

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

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

            @Override
            public void onProviderEnabled(String provider) {
            }

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

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

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

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

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

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

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

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

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

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

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

รหัสสมบูรณ์: https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java

* การร้องขอแต่ละครั้งเพื่อให้ตำแหน่งเสร็จสมบูรณ์ดีที่สุดคือลบการอัปเดตไม่เช่นนั้นแถบสถานะโทรศัพท์จะแสดงไอคอนตำแหน่งเสมอ


-1

หลังจากเห็นคำตอบและคำถามทั้งหมด ( ง่ายที่สุดและแข็งแกร่ง ) ฉันคลิกไลบรารีAndroid-ReactiveLocationเท่านั้น

เมื่อฉันสร้างแอปติดตามตำแหน่ง จากนั้นฉันก็รู้ว่ามันเป็นเรื่องปกติมากที่จะจัดการกับการติดตามตำแหน่งด้วยแบตเตอรี่

ดังนั้นฉันต้องการบอก freshers และนักพัฒนาที่ไม่ต้องการรักษารหัสตำแหน่งด้วยการเพิ่มประสิทธิภาพในอนาคต ใช้ไลบรารีนี้

ReactiveLocationProvider locationProvider = new 

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

พึ่งพาที่จะใส่ใน build.gradle ระดับแอป

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
}

ข้อดีที่จะใช้ lib นี้:

  • lib นี้และจะเป็นการบำรุงรักษาอย่างแข็งขัน
  • คุณไม่ต้องกังวลเกี่ยวกับการเพิ่มประสิทธิภาพแบตเตอรี่ ในฐานะนักพัฒนาได้ทำดีที่สุด
  • ติดตั้งง่ายใส่การพึ่งพาและเล่น
  • เชื่อมต่อกับ Play Services API ได้อย่างง่ายดาย
  • รับตำแหน่งที่ทราบล่าสุด
  • สมัครสมาชิกเพื่อใช้การอัปเดตตำแหน่ง
  • API การตั้งค่าตำแหน่ง
  • จัดการตำแหน่งทางภูมิศาสตร์
  • ตำแหน่ง geocode ไปยังรายการที่อยู่
  • การรับรู้กิจกรรม
  • ใช้ API การดึงข้อมูลสถานที่ในปัจจุบัน
  • คำแนะนำการเติมข้อความอัตโนมัติ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.