如何在Android中不使用getLastKnownLocation方法获取当前的经纬度?

Posted

技术标签:

【中文标题】如何在Android中不使用getLastKnownLocation方法获取当前的经纬度?【英文标题】:How get the current latitud and longitud without use getLastKnownLocation method in Android? 【发布时间】:2015-04-14 16:00:24 【问题描述】:

我正在尝试获取手机的current 位置,为此我使用GPSTracker tutorial,问题总是使用方法getLastKnownLocation 并返回旧位置。

                if (isNetworkEnabled) 
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                Log.d("Network", "Network");
                if (locationManager != null) 
                    location = locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) 
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                    
                
            
            // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) 
                if (location == null) 
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) 
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) 
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        
                    
                
            

你可以看到教程使用NetworkGPS提供者时使用getLastKnownLocation,但我真的很需要当前位置。

不知道怎么弄的!

【问题讨论】:

【参考方案1】:

将 Fused Location Provider API 与 GoogleApiClient 结合使用。您可以找到 apihere。它们旨在提供高精度的位置。使用 GoogleApiClient 使用它。

new GoogleApiClient.Builder(context)
         .addApi(LocationServices.API)
         .addConnectionCallbacks(this)
         .addOnConnectionFailedListener(this)
         .build()

还有其他使用位置提供程序的方法。您不应局限于使用 GPS 和移动网络获得的位置。而是遍历所有位置提供者,并根据您的准确性要求选择那些为您提供高精度的位置提供者。下面的代码就是这样做的:

    Location bestResult = null;
    float bestAccuracy = Float.MAX_VALUE;
    long bestAge = Long.MIN_VALUE;
    List<String> matchingProviders = mLocationManager.getAllProviders();

    for (String provider : matchingProviders) 

        Location location = mLocationManager.getLastKnownLocation(provider);

        if (location != null) 

            float accuracy = location.getAccuracy();
            long time = location.getTime();

            if (accuracy < bestAccuracy) 

                bestResult = location;
                bestAccuracy = accuracy;
                bestAge = time;

            
        
    

    // Return best reading or null
    if (bestAccuracy > minAccuracy
            || (System.currentTimeMillis() - bestAge) > maxAge) 
        return null;
     else 
        return bestResult;
    

您也可以在检查其准确性后直接使用位置对象。您应该利用其他应用程序访问的位置,而不仅仅是依赖 GPS/移动网络获得的位置。

如果您想持续监听位置更新,请实现 Locationlistener 回调以持续获取位置更新。

【讨论】:

【参考方案2】:

如果我没记错的话,该教程相当陈旧,并且不使用融合位置。如果你在 android Studio 中开发,可以考虑试试这个库:https://github.com/mcharmas/Android-ReactiveLocation

使用最新 API 减少代码和融合位置。

简单地获取最后一个已知位置:

ReactiveLocationProvider locationProvider = new ReactiveLocationProvider(context);
locationProvider.getLastKnownLocation()
    .subscribe(new Action1<Location>() 
        @Override
        public void call(Location location) 
            // doSthImportantWithObtainedLocation(location);
        
    );

就是这样!

【讨论】:

获取纬度和经度将是locationProvider.getLatitud? Location 对象包括 getLatitude()getLongitude() developer.android.com/reference/android/location/Location.html【参考方案3】:

我认为其中一个答案使用了 locationListner,但这是一个简单的解决方案,即使 GPS 不可用,它也会通过调用 getBestProvider 返回位置,

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

String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
String provider = locationManager.getBestProvider(criteria, true);
locationManager.requestLocationUpdates(provider, 2000, 0, locationListener);

private final LocationListener locationListener = new LocationListener() 

  public void onLocationChanged(Location location) 
  
    Double latitude = location.getLatitude();
    Double longitude = location.getLongitude();
  

;

【讨论】:

【参考方案4】:
The method mentioned above is the deprecated method and Android has asked developers to use the below method.

https://developer.android.com/training/location/retrieve-current.html

Sample Code


onCreate()
final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) 
            buildAlertMessageNoGps();
        
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

@Override
    protected void onStart() 
        super.onStart();
        // Connect the client.
        mGoogleApiClient.connect();
    

    @Override
    protected void onStop() 
        // Disconnecting the client invalidates it.
        mGoogleApiClient.disconnect();
        super.onStop();
    

    @Override
    public void onConnected(Bundle bundle) 

        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        mLocationRequest.setInterval(1000 * 60 * 5);

        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
    
@Override
    public void onLocationChanged(Location location) 

        Geocoder geocoder;
        List<Address> addresses;
        geocoder = new Geocoder(this, Locale.getDefault());
        try 
            addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
            String address = addresses.get(0).getAddressLine(1);

         catch (IOException e) 
            e.printStackTrace();
        


        editor.commit();
    

【讨论】:

【参考方案5】:

使用下面的代码 -

private class LocationListener extends Activity implements android.location.LocationListener
    Location mLastLocation;
    public LocationListener(String provider)
        Log.e(TAG, "LocationListener " + provider);
        mLastLocation = new Location(provider);
    


   LocationListener[] mLocationListeners = new LocationListener[] 
        new LocationListener(LocationManager.GPS_PROVIDER),
        new LocationListener(LocationManager.NETWORK_PROVIDER)
   ;

    private void initializeLocationManager() 
        Log.e(TAG, "initializeLocationManager");
        if (mLocationManager == null) 
            mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        
    


    @Override
    public void onLocationChanged(Location location) 
        Log.e(TAG, "onLocationChanged: " + location);
        mLastLocation.set(location);
        Toast.makeText(mContext, "Driver location :"+location.getLatitude()+" , "+location.getLongitude(), Toast.LENGTH_SHORT).show();
        //TODO call web service to update driver location to server
        driverLocationUpdateServerRequest(location);
    

    @Override
    public void onProviderDisabled(String provider)
        Log.e(TAG, "onProviderDisabled: " + provider);            
    

    @Override
    public void onProviderEnabled(String provider)
        Log.e(TAG, "onProviderEnabled: " + provider);
    

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



@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    initializeLocationManager();
    try 
        mLocationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[1]);
     catch (java.lang.SecurityException ex) 
        Log.i(TAG, "fail to request location update, ignore", ex);
     catch (IllegalArgumentException ex) 
        Log.d(TAG, "network provider does not exist, " + ex.getMessage());
    
    try 
        mLocationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[0]);
     catch (java.lang.SecurityException ex) 
        Log.i(TAG, "fail to request location update, ignore", ex);
     catch (IllegalArgumentException ex) 
        Log.d(TAG, "gps provider does not exist " + ex.getMessage());
    

 
 

【讨论】:

以上是关于如何在Android中不使用getLastKnownLocation方法获取当前的经纬度?的主要内容,如果未能解决你的问题,请参考以下文章

如何在“发布”版本中不编译某些 Android 菜单项

如何将gridlayoutManager每列的宽度设置为wrapContent在android中不固定大小

getLastKnownLocation null - 如何获取数据?

JavaScript 在 Android Webview 中不起作用?

如何在列表视图之上设置选项卡布局但在 Android 中不覆盖?

导航抽屉在 Android Studio 中不起作用