如何在 Android 中获取位置管理器的最后一个已知位置?

Posted

技术标签:

【中文标题】如何在 Android 中获取位置管理器的最后一个已知位置?【英文标题】:How to get last known location for Location manager in Android? 【发布时间】:2014-10-18 10:51:43 【问题描述】:

我正在使用简单的 位置管理器 对象来获取设备的 lastKnownLocation() 但是在 return 中获取 null object 谁能告诉我为什么?

代码:

public Location getLocation() 
    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);        
    if (locationManager != null)           
        Location lastKnownLocationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (lastKnownLocationGPS != null)              
            return lastKnownLocationGPS;
         else                 
            Location loc =  locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
            System.out.println("1::"+loc);----getting null over here
            System.out.println("2::"+loc.getLatitude());
            return loc;
        
     else             
        return null;
    

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.location);
    getLocation();-----calling service

 

已授予权限:

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

所以有什么需要设置的吗?我已检查我的位置服务是否已在设备中开启 请提供一些工作示例的链接

【问题讨论】:

关注最新文档请developer.android.com/training/location/… :) 也检查一下***.com/a/15997304/3020568 @deniz thnks 我正在实现你给出的第一个链接。我得到 lastLocation 的空值这里是代码 if (mUpdatesRequested) mLocationClient.requestLocationUpdates(mLocationRequest, this); 不使用启用的“使用无线网络”和“位置和 Google 搜索” 您在开发者文档中尝试过该示例吗?希望对你有帮助 【参考方案1】:

在获取最后一个位置之前,也许你想获取当前位置,检查是否为 null 或有。如果您想使用FusedLocationProviderClient ,则未设置最后一个位置 在使用它之前添加这个:

实现 'com.google.android.gms:play-services-location:16.0.0'

在您的 build.gradle(Module: app) 上,并在活动创建时调用方法 zoomMyCuurentLocation()。

private void zoomMyCuurentLocation() 
    LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
        ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
    
    Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
    if (location != null) 
        double lat = location.getLatitude();
        double longi = location.getLongitude();
        LatLng latLng = new LatLng(lat,longi);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14.f));
        Log.d(TAG, "zoomMyCuurentLocation: location not null");
     else 
        setMyLastLocation();
    


private void setMyLastLocation() 
    Log.d(TAG, "setMyLastLocation: excecute, and get last location");
    FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
        return;
    
    fusedLocationClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() 
        @Override
        public void onSuccess(Location location) 
            if (location != null)
                double lat = location.getLatitude();
                double longi = location.getLongitude();
                LatLng latLng = new LatLng(lat,longi);
                Log.d(TAG, "MyLastLocation coordinat :"+latLng);
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14.f));
            
        
    );

【讨论】:

【参考方案2】:

对此的回答很愚蠢……我重新启动了我的设备……它工作了……请确保您的位置服务已启用并正常工作

【讨论】:

【参考方案3】:

我用来获取地点名称的位置是

GPSTracker gpsTracker = new GPSTracker(CameraActivity.this);
String stringLatitude = "", stringLongitude = "", nameOfLocation="";
    if (gpsTracker.canGetLocation()) 
        stringLatitude = String.valueOf(gpsTracker.latitude);
        stringLongitude = String.valueOf(gpsTracker.longitude);
        nameOfLocation = ConvertPointToLocation(stringLatitude,stringLongitude);
    

public String ConvertPointToLocation(String Latitude, String Longitude) 
    String address = "";
    Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
    try 
        List<Address> addresses = geoCoder.getFromLocation(
                Float.parseFloat(Latitude), Float.parseFloat(Longitude), 1);

        if (addresses.size() > 0) 
            for (int index = 0; index < addresses.get(0)
                    .getMaxAddressLineIndex(); index++)
                address += addresses.get(0).getAddressLine(index) + " ";
        
     catch (IOException e) 
        e.printStackTrace();
    

    return address;

GPSTracker.java

package in.appology.lss;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

/**
 * Create this Class from tutorial :
 * http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial
 * 
 * For Geocoder read this :
 * http://***.com/questions/472313/android-reverse
 * -geocoding-getfromlocation
 * 
 */

public class GPSTracker extends Service implements LocationListener 
private final Context mContext;

// flag for GPS Status
boolean isGPSEnabled = false;

// flag for network status
boolean isNetworkEnabled = false;

boolean canGetLocation = false;

Location location;
double latitude;
double longitude;

// The minimum distance to change updates in metters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10
                                                                // metters

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

// Declaring a Location Manager
protected LocationManager locationManager;

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


public Location getLocation() 
    try 
        locationManager = (LocationManager) mContext
                .getSystemService(LOCATION_SERVICE);

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

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

        if (!isGPSEnabled && !isNetworkEnabled) 
            // no network provider is enabled
         else 
            this.canGetLocation = true;

            // First get location from Network Provider
            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);
                    updateGPSCoordinates();
                
            

            // 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);
                        updateGPSCoordinates();
                    
                
            
        
     catch (Exception e) 
        // e.printStackTrace();
        Log.e("Error : Location",
                "Impossible to connect to LocationManager", e);
    

    return location;


public void updateGPSCoordinates() 
    if (location != null) 
        latitude = location.getLatitude();
        longitude = location.getLongitude();
    


/**
 * Stop using GPS listener Calling this function will stop using GPS in your
 * app
 */

public void stopUsingGPS() 
    if (locationManager != null) 
        locationManager.removeUpdates(GPSTracker.this);
    


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

    return latitude;


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

    return longitude;


/**
 * Function to check GPS/wifi enabled
 */
public boolean canGetLocation() 
    return this.canGetLocation;


/**
 * Function to show settings alert dialog
 */
public void showSettingsAlert() 
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

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

    // Setting Dialog Message
    alertDialog
            .setMessage("Please enable location in settings for accurate results!");

    // On Pressing Setting 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 cancel button
    alertDialog.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() 
                @Override
                public void onClick(DialogInterface dialog, int which) 
                    dialog.cancel();
                
            );

    alertDialog.show();


/**
 * Get list of address by latitude and longitude
 * 
 * @return null or List<Address>
 */
public List<Address> getGeocoderAddress(Context context) 
    if (location != null) 
        Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
        try 
            List<Address> addresses = geocoder.getFromLocation(latitude,
                    longitude, 1);
            return addresses;
         catch (IOException e) 
            // e.printStackTrace();
            Log.e("Error : Geocoder", "Impossible to connect to Geocoder",
                    e);
        
    

    return null;


/**
 * Try to get AddressLine
 * 
 * @return null or addressLine
 */
public String getAddressLine(Context context) 
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) 
        Address address = addresses.get(0);
        String addressLine = address.getAddressLine(0);

        return addressLine;
     else 
        return null;
    


/**
 * Try to get Locality
 * 
 * @return null or locality
 */
public String getLocality(Context context) 
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) 
        Address address = addresses.get(0);
        String locality = address.getLocality();

        return locality;
     else 
        return null;
    


/**
 * Try to get Postal Code
 * 
 * @return null or postalCode
 */
public String getPostalCode(Context context) 
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) 
        Address address = addresses.get(0);
        String postalCode = address.getPostalCode();

        return postalCode;
     else 
        return null;
    


/**
 * Try to get CountryName
 * 
 * @return null or postalCode
 */
public String getCountryName(Context context) 
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) 
        Address address = addresses.get(0);
        String countryName = address.getCountryName();

        return countryName;
     else 
        return null;
    


@Override
public void onLocationChanged(Location location) 


@Override
public void onProviderDisabled(String provider) 


@Override
public void onProviderEnabled(String provider) 


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


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


【讨论】:

我正在使用 googlePlayLocation 服务而不是 GPS 它正在运行获取位置的服务。问这个问题的人从来没有提到在特定的时间间隔进行位置报告。不适合提出的问题【参考方案4】:

我发现的最佳方法:

private Location getLastKnownLocation() 
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
        return null;
    

    List<String> providers = locationManager.getProviders(true);
    Location bestLocation = null;
    for (String provider : providers) 
        Location l = locationManager.getLastKnownLocation(provider);
        if (l == null) 
            continue;
        
        if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) 
            // Found best last known location:
            bestLocation = l;
        
    

    return bestLocation;

locationManager变量可以从系统服务LOCATION获取。

【讨论】:

缺失:LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);上面列出提供者【参考方案5】:
            // Get the location from the given provider
            Location location = locationManager
                    .getLastKnownLocation(provider);

            locationManager.requestLocationUpdates(provider, 1000, 1, this);

【讨论】:

【参考方案6】:

要获取最后一个位置,您可以参考上面提供的答案,您可以在其中使用 Location Manager 或 FusedLocationClient

但您也可以使用比其他方法更快的 LocationServices

所以让我提供一个简短的工作:

1) 在你的 gradle 应用文件中添加这两个依赖项

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

2) 在应用标签外的清单文件中添加这些权限

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

3) 在onCreate之外声明变量

private FusedLocationProviderClient fusedLocationClient;

4) 现在在 onCreate 中:

fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
fetchLastLocation();

5) 没有定义fetchLastLocation方法

private void fetchLastLocation() 

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
                // TODO: Consider calling
                //    Activity#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 Activity#requestPermissions for more details.
//                    Toast.makeText(MainActivity.this, "Permission not granted, Kindly allow permission", Toast.LENGTH_LONG).show();
                showPermissionAlert();
                return;
            
        
        fusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, new OnSuccessListener<Location>() 
                    @Override
                    public void onSuccess(Location location) 
                        // Got last known location. In some rare situations this can be null.
                        if (location != null) 
                            // Logic to handle location object
                            Log.e("LAST LOCATION: ", location.toString());
                        
                    
                );

    

6) 现在定义另外两种权限请求方法

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
        switch (requestCode) 
            case 123: 
                // If request is cancelled, the result arrays are empty.
                if (grantResults[0] == PackageManager.PERMISSION_DENIED) 
                    // permission was denied, show alert to explain permission
                    showPermissionAlert();
                else
                    //permission is granted now start a background service
                    if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                            && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) 
                        fetchLastLocation();
                    
                
            
        
    

    private void showPermissionAlert()
        if (ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
            ActivityCompat.requestPermissions(MainHomeActivity.this, new String[]Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, 123);
        
    

注意:用你的类上下文替换上下文

您将在 Logcat 中获得您的位置。

希望这会希望你或其他人

【讨论】:

【参考方案7】:

以下是我试图获取最后一个位置的方式。

private void setUpMap()
    //Location location = mMap.getMyLocation();
    mMap.setMyLocationEnabled(true);
    //mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    mMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() 
        @Override
        public void onMyLocationChange(Location location) 
             mMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())).title("My Location"));
             mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),location.getLongitude()),10));
             mMap.setOnMyLocationChangeListener(null);
        
    );

【讨论】:

以上是关于如何在 Android 中获取位置管理器的最后一个已知位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有互联网连接的情况下在android中获取当前纬度和经度?

android常用的布局管理器都有哪些,简述各布局管理器的布局特点

我如何获得我在 android 中的最后一个已知位置?

如何根据两个不同活动中其他微调器的位置更改微调器的位置

Android 11:如何获取当前位置

Android怎么实现点击按钮获取当前位置的信息,没有地图的情况下。