Solution 1 :
This code works just fine in one of my projects:
public class LocationManager {
private static LocationManager requestManager;
private FusedLocationProviderClient mLocationProviderClient;
private Location mLocation;
private Location mMyCurrentLocation;
private locationSuccessListener mListener;
public Location getLocation() {
return mLocation;
}
public void setLocation(Location location) {
mLocation = location;
}
private LocationManager(FusedLocationProviderClient fusedLocationProviderClient) {
this.mLocationProviderClient = fusedLocationProviderClient;
}
public static LocationManager createInstance(FusedLocationProviderClient fusedLocationProviderClient) {
if (requestManager != null) {
return requestManager;
} else {
return requestManager = new LocationManager(fusedLocationProviderClient);
}
}
public static LocationManager getInstance() {
return requestManager;
}
public void setLocation(Activity activity) {
mListener = (locationSuccessListener) activity;
LocationCallback callback = new LocationCallback();
LocationRequest locationRequest = new LocationRequest();
Task<Void> r = mLocationProviderClient.requestLocationUpdates(locationRequest, callback, Looper.getMainLooper());
r.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
mLocationProviderClient.getLastLocation().addOnSuccessListener(activity, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
mMyCurrentLocation = location;
mLocation = location;
if (location != null) {
mListener.onLocationReceived();
mLocationProviderClient.removeLocationUpdates(callback);
}
}
});
}
});
}
public Location getMyCurrentLocation() {
return mMyCurrentLocation;
}
public interface locationSuccessListener {
void onLocationReceived();
}
You need to do something like that:
public class PlacesActivity extends SingleFragmentActivity implements NavigationView.OnNavigationItemSelectedListener, LocationManager.locationSuccessListener
and then in your activity you will get this:
@Override
public void onLocationReceived() {
Location l = LocationManager.getInstance().getMyCurrentLocation();
if (l==null){
Toast.makeText(this, "unable to get location", Toast.LENGTH_SHORT).show();
}
}
to get permission you suppose to do something like this:
if (ContextCompat.checkSelfPermission(Objects.requireNonNull(getActivity()), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
0);
Problem :
So there are many similar questions asked based on this, and I have also got a working solution. However, this seems to only work on my physical Android device. If I were to use it with the emulator, the method returns a null value and I don’t know why. Many sources mention that there is a better alternative to the code that I am currently using but they don’t mention what/how exactly. This is the code that I am using to get the current location of my device:
@SuppressWarnings("MissingPermission")
private LatLng getCurrentLocation() {
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
String locationProvider = LocationManager.NETWORK_PROVIDER;
assert locationManager != null;
android.location.Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
return new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
}
I also don’t like the fact that I have to suppress warnings. Sources that I have looked at include:
https://developer.android.com/training/location/retrieve-current.html#java
What is the simplest and most robust way to get the user’s current location on Android?
The first one doesn’t work, I get a null value. The second one looks overly complicated for a simple result that I am seeking.
Comments
Comment posted by Shrimat Kapoor
Thanks, but is it necessary to have permissions in the setLocation method? Or is that just my IDE? Also, what exactly is that method doing? I have created an instance of this class, and passed a new fusedlocationprovider. Should I call the getMyCurrentLocation method where I need it directly or do something before this? I think I am getting a null value returned if I don’t do anything before this
Comment posted by Shrimat Kapoor
I think I have to also call set location and pass the current activity. However, you say that my activity needs to implement that interface inside the class, how exactly do I go about that? What do I implement in the onLocationReceived method?
Comment posted by Shrimat Kapoor
What exactly is RequestManager in your onLocationReceived method? And also, do I need to create a location manager or do I just call that method and then create a Location field that stores the current location and then can be used else where?
Comment posted by Shrimat Kapoor
I’m still getting null values returned, even after calling setLocation, could you please give some more detail 🙁
Comment posted by Shrimat Kapoor
Also, to note, if you use getInstance on a class directly, won’t the instance returned be null by default because it hasn’t been initialised?