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

问题描述 投票:0回答:10

我正在使用简单的位置管理器对象来获取设备的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" />

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

android geolocation locationmanager
10个回答
6
投票

在获取最后一个位置之前,也许您想获取当前位置,检查是否为空或有。如果没有设置最后一个位置,如果你想使用 FusedLocationProviderClient 在使用之前添加以下内容:

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

在你的 build.gradle(Module: app) 上,并调用方法 ZoomMyCurentLocation() 来创建活动。

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

4
投票

愚蠢的事情作为答案...我重新启动了我的设备...并且它起作用了...请确保您的位置服务已启用并正常工作


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://stackoverflow.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;
}
}

3
投票

要获取最后一个位置,您可以参考上面提供的答案,您可以使用位置管理器或 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) 在 applicationtag 之外的清单文件中添加这些权限

<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 中获取您的位置。

希望这会希望你或其他人


3
投票

我发现的最佳方法:

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
变量。


2
投票
            // Get the location from the given provider
            Location location = locationManager
                    .getLastKnownLocation(provider);

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

1
投票

以下是我尝试获取最后位置的方法。

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

1
投票

用 Kotlin 解决这个问题: 抱歉,可怕的缩进

  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. 在 applicationtag 之外的清单文件中添加这些权限

     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
  3. 在 onCreate 之外声明变量

     private lateinit var fusedLocationClient: FusedLocationProviderClient
    
  4. 现在在 onCreate 中:

     fusedLocationClient= LocationServices.getFusedLocationProviderClient(this)
    
     getCurrentLocation()
    
  5. 没有定义 fetchLastLocation 方法 注意:这里的getCurrentLocation表示的是最后一个位置。

     private fun getCurrentLocation(){
     if(checkPermissions())
     {
         if(isLocationEnabled()){
             //final latitude and longitude
             if (ActivityCompat.checkSelfPermission(
                     this,
                     Manifest.permission.ACCESS_FINE_LOCATION
                 ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                     this,
                     Manifest.permission.ACCESS_COARSE_LOCATION
                 ) != PackageManager.PERMISSION_GRANTED
             ) {
                 requestPermission()
                 return
             }
             // fusedLocationClient.getCurrentLocation()
             fusedLocationClient.lastLocation.addOnCompleteListener(this){ task->
                 val location:Location?=task.result
                 if(location==null)
                 {
                     Toast.makeText(this,"NULL Received",Toast.LENGTH_SHORT).show()
                 }
                 else{
                     Toast.makeText(this,"Location SUCCESS",Toast.LENGTH_SHORT).show()
                     val geocoder = Geocoder(this, Locale.getDefault())
                     val addresses: MutableList<android.location.Address>? = geocoder.getFromLocation(location.latitude, location.longitude, 1)
                     cityName = addresses!![0].locality
                     startActivity(intent)
                 }
             }
         }
         else
         {
             Toast.makeText(this,"Turn on location",Toast.LENGTH_SHORT).show()
             val intent= Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
             startActivity(intent)
         }
     }
     else
     {
         //request permission here
         requestPermission()
     }
    

    }

  6. 现在定义其他权限请求方法

     private fun requestPermission() {
     ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_COARSE_LOCATION,android.Manifest.permission.ACCESS_FINE_LOCATION),
         PERMISSION_REQUEST_ACCESS_LOCATION)
     }
    
     companion object{
     private const val PERMISSION_REQUEST_ACCESS_LOCATION=100
     }
    
     private fun checkPermissions():Boolean {
     if (ActivityCompat.checkSelfPermission(
             this,
             android.Manifest.permission.ACCESS_FINE_LOCATION
         ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
             this,
             android.Manifest.permission.ACCESS_COARSE_LOCATION
         ) == PackageManager.PERMISSION_GRANTED
     ) {
         return true
     }
     return false
     }
    
     override fun onRequestPermissionsResult(
     requestCode: Int,
     permissions: Array<out String>,
     grantResults: IntArray
     ) {
     super.onRequestPermissionsResult(requestCode, permissions, grantResults)
     if(requestCode== PERMISSION_REQUEST_ACCESS_LOCATION)
     {
         if(grantResults.isNotEmpty() && grantResults[0]==PackageManager.PERMISSION_GRANTED){
             Toast.makeText(applicationContext,"Granted",Toast.LENGTH_SHORT).show()
             getCurrentLocation()
         }
         else{
             Toast.makeText(applicationContext,"DENIED",Toast.LENGTH_SHORT).show()
         }
     }
     }
    
     private fun isLocationEnabled():Boolean{
     val locationManager:LocationManager=getSystemService(Context.LOCATION_SERVICE) as LocationManager
     return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)||locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
     }
    

0
投票

这里有一个更好的解决方案:

@Nullable
public static Location getLastKnownLocation(Context context, LocationManager locationManager) {
    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
            ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return null;
    }

    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);

    String provider = locationManager.getBestProvider(criteria, true);
    if (provider == null) return null;

    return locationManager.getLastKnownLocation(provider);
}

这行:

criteria.setAccuracy(Criteria.ACCURACY_FINE);
就可以了。


0
投票

我在这个问题上做了完整的工作在此处输入链接描述。这是中等故事。

© www.soinside.com 2019 - 2024. All rights reserved.