在Android上获取用户当前位置的最简单,最强大的方法是什么?

时间:2010-06-29 21:59:26

标签: android geolocation location latitude-longitude

Android上的LocationManager API似乎对于仅需要偶尔粗略估计用户位置的应用程序来说有点痛苦。

我正在处理的应用程序本身并不是一个位置应用程序,但它确实需要获取用户的位置才能显示附近的商家列表。它不需要担心用户是否正在四处移动或类似的事情。

这是我想做的事情:

  1. 向用户显示附近位置列表。
  2. 预加载用户的位置,以便在Activity X中我需要时,它将可用。
  3. 我并不特别关心更新的准确性或频率。只要没有办法,抓住一个位置就足够了。也许如果我想要花哨,我会每隔几分钟左右更新一次这个位置,但这不是一个重要的优先事项。
  4. 只要有GPS或网络位置提供商,就可以使用任何设备。
  5. 看起来它应该不那么难,但在我看来,我必须启动两个不同的位置提供商(GPS和NETWORK)并管理每个生命周期。不仅如此,我还必须在多个活动中复制相同的代码以满足#2。我过去曾尝试使用getBestProvider()将解决方案缩减为仅使用一个位置提供商,但这似乎只能为您提供最好的“理论”提供商,而不是实际上会为您提供最佳服务的提供商结果

    有没有更简单的方法来实现这个目标?

29 个答案:

答案 0 :(得分:913)

这就是我的所作所为:

  1. 首先,我检查哪些提供程序已启用。有些可能在设备上被禁用,有些可能在应用程序清单中被禁用。
  2. 如果有任何提供者可用,我会启动位置监听器和超时计时器。在我的例子中,这是20秒,可能还不够GPS,所以你可以放大它。
  3. 如果我从位置监听器获得更新,我使用提供的值。我停止了听众和计时器。
  4. 如果我没有得到任何更新和计时器过去,我必须使用最后已知的值。
  5. 我从可用的提供商那里获取最新的已知值并选择最新的值。
  6. 以下是我使用课程的方式:

    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。

答案 1 :(得分:38)

在搜索最佳实施后,如何获得最佳的精确用户位置,我设法结合所有最好的方法,并提出以下课程:

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

如果启用GPS,此课程会尝试连接min_gps_sat_count个卫星。否则返回LocationManager.getBestProvider()位置。检查代码!

答案 2 :(得分:27)

使用Fedor的解决方案,我经历了多次回调gotLocation的执行。 这似乎是由于被覆盖的LocationListener.onLocationChanged方法中的竞争条件,当gotLocation方法'足够长'时。我不确定,但我猜removeUpdates阻止了Looper队列中新消息的排队,但它不会删除那些已经入队但尚未消耗的消息。因此竞争条件。

为了减少这种错误行为的可能性,可以在触发onLocationChanged事件之前调用removeUpdates,但仍然存在竞争条件。

我找到的最佳解决方案是将requestLocationUpdates替换为requestSingleUpdate

这是我的版本,基于Fedor的解决方案,使用Handler向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);
    }
}

我在定制的循环线程中使用此类,如下所示:

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

其中,坐标是一个具有两个属性的简单类:纬度和经度。

答案 3 :(得分:15)

我创建了一个小型应用程序,逐步描述获取当前位置的GPS坐标。

enter image description here

以下网址中的完整示例源代码:


  

Get Current Location coordinates , City name - in Android


查看工作原理:

  • 我们需要做的就是在清单文件中添加此权限

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">  
    </uses-permission>
    
  • 并像这样创建LocationManager实例

    LocationManager locationManager = (LocationManager) 
                                      getSystemService(Context.LOCATION_SERVICE);
    
  • 检查GPS是否已启用

  • 然后实现LocationListener和Get Coordinates

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

答案 4 :(得分:11)

您可以随时使用LocationManager.getLastKnownLocation(),但就像它说它可能已过时。

获得一般位置的简单方法可能是注册网络(通常非常快)。

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

然后做

locationManager.removeUpdates(this);

在侦听器的onLocationChanged()方法中。

答案 5 :(得分:6)

我在current location上写了详细的教程demonuts.com。您可以在此处找到更多说明,也可以下载整个演示源代码以便更好地理解。

那里已有很多答案,但我想展示使用Google API获取位置的最新方式,因此新程序员可以使用新方法:

首先,把它放在gradle文件中

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

然后实现必要的接口

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

声明实例

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

将其放在onCreate()

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

最后,重写必要的方法

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

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

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

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

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

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

    }

在运行应用之前,不要忘记在设备中启动GPS。

答案 6 :(得分:5)

我不确定Location-Based Services是否可以从GPS以外的其他基础设施获取位置,但根据该文章,它似乎有可能:

  

应用程序可以调用任何一个   几种定位方法。

     

使用手机网络:   当前的小区ID可用于   识别基站收发站   (BTS)设备正在通信   和BTS的位置。   显然,这种方法的准确性   取决于细胞的大小,和   可能是非常不准确的。一个GSM小区   可能是2到20之间的任何地方   公里直径。其他   与细胞ID一起使用的技术可以   在150米范围内达到精度。

     

使用卫星:全球   定位系统(GPS),受控制   由美国国防部使用   一个由24颗卫星组成的星座   绕地球轨道运行。 GPS决定了   设备的位置通过计算   时间的差异来自   不同的卫星需要到达   接收器。 GPS信号被编码,因此   必须配备移动设备   带GPS接收器。 GPS是   可能是最准确的方法   (如果是GPS,则在4到40米之间   接收器有一个清晰的天空视图),   但它有一些缺点:额外的   硬件可能是昂贵的,消耗   电池在使用时,需要   冷启动后得到一些热身   对可见卫星的初步修正。   它也遭受“峡谷效应”   在城市,卫星能见度   是断断续续的。

     

使用短程   定位信标:相对而言   小区域,如单个   建设,局域网可以   提供位置和其他   服务。例如,适当的   配备的设备可以使用蓝牙   短程定位。

答案 7 :(得分:5)

Actualy我们可以使用两个提供商(GPS&amp; NETWORK)。他们只是分享一个公众倾听者:

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

这是必要的,因为始终需要及时调用OnLocationChanged()方法。

答案 8 :(得分: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);

答案 9 :(得分: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.ConnectionCallbacksGooglePlayServicesClient.OnConnectionFailedListenerLocationListener

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

然后,在LocationClient的{​​{1}}方法中设置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); } ; ActivityonConnected()连接时调用的方法。 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"); } } ,以便在绝对必要时仅使用额外的电池,因此GPS无法无限期运行。必须连接LocationClient才能从中获取数据。

LocationClient

获取用户的位置。首先尝试使用public void onResume() { super.onResume(); mLocationClient.connect(); } public void onStop() { if (mLocationClient.isConnected()) { mLocationClient.removeLocationUpdates(this); } mLocationClient.disconnect(); super.onStop(); } ;如果失败,请回到LocationClient

LocationManager

答案 10 :(得分:3)

这是提供用户当前位置的代码

创建地图激活:

public class Maps extends MapActivity {

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

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

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

            public void onProviderEnabled(String arg0) {}

            public void onProviderDisabled(String arg0) {}

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

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

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

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

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

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

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

    class MapOverlay extends Overlay {

        private GeoPoint pointToDraw;

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

        public GeoPoint getPointToDraw() {
            return pointToDraw;
        }

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

<强> main.xml中:

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

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

    </LinearLayout>

并在清单中定义以下权限:

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

答案 11 :(得分:2)

编辑:使用Google Play服务库中的最新位置服务API 进行了更新(2014年7月)

我建议您使用Google Play服务库中提供的新Location Service API,它提供了一个功能更强大的高级框架,可自动执行位置提供程序选择和电源管理等任务。根据官方文档:&#34; ...位置API使您可以轻松构建位置感知应用程序,而无需关注底层定位技术的细节。它们还可以通过使用设备硬件的所有功能来最小化功耗。&#34;

有关详细信息,请访问:Making Your App Location-Aware

要查看使用最新位置服务API的完整示例,请访问:Android LocationClient class is deprecated but used in documentation

答案 12 :(得分:2)

尽管这里已经给出了答案。我只想在这种情况下遇到这个问题。

我的要求是我需要在最多30到35秒内获得用户的当前位置,所以这是我在Nirav Ranpara's Answer之后做出的解决方案。

1。我制作了 MyLocationManager.java 类来处理所有GPS和网络内容

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

import com.app.callbacks.OnLocationDetectectionListener;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        }

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

        }

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

        }

        @Override
        public void onLocationChanged(Location location) {

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

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

        }

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

        }

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

        }

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

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

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

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

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

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

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

2. 我创建了一个接口(回调) OnLocationDetectectionListener.java ,以便将结果传回给调用片段或活动

import android.location.Location;

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

3。然后我制作了一个实现OnLocationDetectectionListener界面的 MainAppActivty.java 活动,这就是我在其中收到我的位置的方式

public class MainAppActivty extends Activity implements
        OnLocationDetectectionListener {

    private Location currentLocation;
    private MyLocationManager mLocationManager;

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

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

4. 将以下权限添加到清单文件

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

希望这对其他人有帮助:))

答案 13 :(得分:2)

要获取并显示用户的当前位置,您还可以使用MyLocationOverlay。假设您的活动中有mapView字段。要显示用户位置,您需要做的就是:

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

从GPS或网络获取当前位置。如果两者都失败,enableMyLocation()将返回false

至于该地区周围事物的位置,ItemizedOverlay应该可以解决问题。

我希望我没有误解你的问题。祝你好运。

答案 14 :(得分:1)

GeoLocation的简单和最佳方式。

LocationManager lm = null;
boolean network_enabled;


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

            network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

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


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

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

                        @Override
                        public void run() 
                        {

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

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


                                    if (network_enabled) {

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

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

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


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

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


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



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

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

                                                        isInternetPresent = cd.isConnectingToInternet();

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

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

                                                    }   
                                                }

                                            }

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

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

                                            }

                                            public void onProviderDisabled(String provider) {


                                            }
                                        };



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

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

                                    }



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

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

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

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

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

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

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

                                    if(Data.fb_access_token == "")
                                    {

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

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

                                        isInternetPresent = cd.isConnectingToInternet();

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

                                    }   

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


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

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


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

答案 15 :(得分:1)

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

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

答案 16 :(得分:1)

这里有点晚了,但在这种情况下我会使用谷歌地图API并使用google地图的lat和long API标记附近的位置。如果您可以在地图上显示他/她的位置,那么用户体验会更好。无需担心用户位置的更新或使用android api进行搜索。让谷歌地图为你处理内部。

@emmby可能已经在他的应用程序中解决了这个问题但是为了将来的参考,我建议其他开发人员使用Google Maps API查看特定于位置的内容。

修改:显示user location in google maps

的链接

答案 17 :(得分:1)

要在android中获取位置更新需要很多东西, 需要大量的bolierplate代码。

你需要照顾

  • Google Play服务可用性检查,
  • 更新Google Play服务(如果旧版或不可用)
  • 对话创建GoogleApiClient及其回调连接,断开连接等。
  • 停止并释放资源以进行位置更新
  • 处理位置权限方案
  • 检查位置服务是开启还是关闭
  • 获取上次知道的位置也不是那么容易
  • 如果在一定时间后没有获得位置,则回退到上一个已知位置

我创建了Android-EasyLocation (small android library),它将关注所有这些内容,您可以专注于业务逻辑。

您只需要扩展 EasyLocationActivity

requestSingleLocationFix(easyLocationRequest);

requestLocationUpdates(easyLocationRequest);

结帐示例应用和https://github.com/akhgupta/Android-EasyLocation

所需的步骤

答案 18 :(得分:1)

这是我请求用户权限的方式。

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

然后在App Gradle文件中添加Google的位置依赖项。

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

答案 19 :(得分:1)

从过去一年多的时间开始,我使用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" />

答案 20 :(得分:0)

使用FusedLocationProviderApi这是最新的API,也是获取Android位置的最佳选择。 在build.gradle文件中添加它

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

您可以通过此网址获取完整的源代码 http://javapapers.com/android/android-location-fused-provider/

答案 21 :(得分:0)

这就是我的所作所为:

  1. 首先,我检查是否启用了NETWORK或GPS提供程序。有些可能在设备上被禁用,有些可能在应用程序清单中被禁用。如果启用了任何提供程序,我将获取此提供程序的缓存最后位置,并为此提供程序启动位置更新侦听程序。
  2. 如链接中所述,有一种方法可以确定某个位置是否优于上次收到的位置: - https://developer.android.com/guide/topics/location/strategies.html#BestEstimate
  3. 如果我从位置监听器获得更新,我会检查此位置是否优于以前收到的位置。如果最好将此位置替换为之前的最佳位置(mFinalLocation)。
  4. 还有一个处理程序(计时器),持续两分钟,最终停止服务,在onDestroy()服务方法中,停止侦听每个提供程序的位置更新。
  5. 以下是服务代码。您可以根据所需的位置更新频率运行它。

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

答案 22 :(得分:0)

最近重构了获取代码的位置,学习了一些好的想法,最后实现了一个比较完善的库和Demo。

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

*每个请求完成位置,最好删除更新,否则手机状态栏将始终显示定位图标。

答案 23 :(得分:0)

看到所有答案后,提问(最简单,最强健)。我只点击了库Android-ReactiveLocation

当我创建位置跟踪应用时。然后我意识到它是非常典型的处理位置跟踪与电池优化。

所以我想告诉新手和开发人员,他们不希望通过未来的优化来维护他们的位置代码。使用此库。

ReactiveLocationProvider locationProvider = new 

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

放入app level 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 主动维护。
  • 你不担心电池优化。正如开发人员已尽力而为。
  • 易于安装,依赖和玩耍。
  • 轻松连接到Play Services API
  • 获取最后的已知位置
  • 使用
  • 订阅位置更新
  • 位置设置API
  • 管理地理围栏
  • 地理位置位置到地址列表
  • 活动识别
  • 使用当前位置API获取位置
  • 自动填充建议

答案 24 :(得分:0)

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

答案 25 :(得分:0)

在Activity类中创建一个自定义方法:

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

    }

答案 26 :(得分:0)

@Fedor解决方案的改进。 我们可以使用位置管理器的 requestSingleUpdate 方法,而不是使用“ 0”时间间隔和“ 0”距离来请求位置。更新的代码(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方法之前,必须授予所需的位置权限。

答案 27 :(得分:0)

其中一些现在已经过时了,所以即时通讯,

FusedLocationProviderClient fusedLocationProviderClient; //set global variable
Location currentLocation;//set global var
private boolean mLocationPermissionGranted; //set global var
 fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getContext()); //write this oncreate
        fetchLastLocation();  // call the funct for current location
//here is the function
private void fetchLastLocation() {

    if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(getActivity(),new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_CODE);
        return;
    }else {
        mLocationPermissionGranted=true;
    }
    Task<Location> task= fusedLocationProviderClient.getLastLocation();
    task.addOnSuccessListener(new OnSuccessListener<Location>() {
        @Override
        public void onSuccess(Location location) {
            if(location != null){
                currentLocation =location;
               Toast.makeText(getContext(), currentLocation.getLatitude()+"" +
                        " "+currentLocation.getLongitude(), 
                   Toast.LENGTH_SHORT).show();
//if you want to show in google maps
                SupportMapFragment supportMapFragment =(SupportMapFragment)
                        getChildFragmentManager().findFragmentById(R.id.map);
                supportMapFragment.getMapAsync(MapsFragment.this);
            }
        }
    });


}

答案 28 :(得分:-2)

在我回答之前,我只想提前了解我与Neura的关系。 现在回答你的问题。因此,您可以使用我们的SDK,而不是浪费时间在编码上以获取用户的位置。整合不到30分钟。 Neura为您提供用户的位置/活动,您可以相应地配置应用程序,以便在收到数据后执行某些任务。以下是使用Neura而非其他Activity识别API的几个原因:

  1. 无需对大量行进行编码即可了解您的用户。
  2. 为您提供准确的结果。
  3. 消耗不到1%的电池。