Why is this double null? - java

I' m in a service, and I just need the latitude and longitude. Just two doubles. So, I did the following:
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
}
For some reason, the latitude and latitude are null. The documentation says this is possible if the information for location is unavailable, but it should be available, since I first check if the permissions are there in the if statement, right? In the phone that I am testing on, I do have location enabled. Why is the latitude and longitude null?

If you try this instead, what is the output?
locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);

It's because, even if location is enabled, there is no "lastKnownLocation" available yet. If you go to (for example) google maps app and ask for current location, after location is successfully fetched, go to your app and it will work (lat and lon != null).
EDIT: I don't know the code for android location service API, but for google maps API is something like this (i'm sure is similar):
public void methodThatUseLocation() {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), PERMISSIONS, MainActivity.REQUEST_LOCATION);
} else {
Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (lastLocation != null) {
Double latitude = lastLocation.getLatitude();
Double longitude = lastLocation.getLongitude();
// do something with latitude and longitude
} else {
requestLocationUpdate();
}
}
}
private void requestLocationUpdate() {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), PERMISSIONS, MainActivity.REQUEST_LOCATION);
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
}

The reason is, you are checking last known location, and if there were no locations previously fetched by this provider, all corresponding parameters will be null. Method getLastKnownLocation reuses information fetched by other apps/services, and it can happen that there were no information saved.
You can try to make single location update using method requestSingleUpdate, so you won't depend on your device state.

Related

Unable to Get Coordinates from Location Service on Android Studio

I am new to Android Studio and am trying to retrieve the co-ordinates of an Android device using Location Service.
I have all the relevant permissions enabled in the manifest (the Coarse and Fine locations, and the Internet).
In my MainActivity.java, I have the following. However, when I run it in Android Studio, for the 3 test cases I have in the activity, the TextView ShowLocation always become "Something else", meaning that it went to the third case where location is null (no location detected?) but permission has been granted properly.
What am I doing wrong here? Is it because I could not test Location Service in Android Studio? How can I test and obtain co-ordinate values in an Android application using Android Studio?
A snippet of MainActivity.java
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
}
Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (loc != null) {
latitude = String.valueOf(loc.getLatitude());
showLocation.setText("Latitude" + latitude);
}
else {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
showLocation.setText("No GPS Permission granted");
} else
showLocation.setText("Something else");
}

.isProviderEnabled(LocationManager.NETWORK_PROVIDER) returns always false when gps is off?

Is it possible to get the location from NETWORK if GPS is OFF ?
My Demo can get the current user-location from NETWORK and from GPS but only if GPS is ON.
If I try to get the location from LastKnownLocation, I get null too.
#Override
protected void onResume() {
super.onResume();
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) {
startActivity(new Intent(MainActivity.this, Permissions.class));
return;
}
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
isGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPS && !isNetwork) {
Log.d("TAG", "gps and network false");
}else {
if (isGPS) {
loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (loc != null) {
Log.i("TAG", "gps loc found");}
}
if (isNetwork) {
loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (loc != null) {
Log.i("TAG", "network loc found");
}
}
I have tested this code below. it returns the location null too, if I make the device-gps off :
GPSTracker.java
If you are trying to request the location from the network as a fallback to GPS, you will need to have ACCESS_COARSE_LOCATION enabled. Also, even with the permission enabled, you must request a location update, to refresh and update the last network position. Only after that, you'll have the last known location available, otherwise, you'll get null indeed.
To make your code work, you probably just need to call your GPSTracker.getLocation() before your line with
getSystemService(Context.LOCATION_SERVICE);
You can check the documentation for getLastKnownLocation here:
https://developer.android.com/reference/android/location/LocationManager#getLastKnownLocation(java.lang.String)
Gets the last known location from the given provider, or null if there
is no last known location. The returned location may be quite old in
some circumstances, so the age of the location should always be
checked.
👉   This will never activate sensors to compute a new location, and will
only ever return a cached location.

Getting longitude and latitude from lastKnownLocation()?

I've got a activity that onCreate, it calculates the distance between your location and a event that is nearby, I've used lastKnownLocation to get the current device location and put a marker of it on a google map, but I need it to write the longitude and latitude outside of it's method to be used to calculate distances.
I've used LocationManager to get the rough coordinates but these aren't accurate enough and has a distance of 50 miles for something that's not even half a mile away. I currently have it so will overwrite longitude and latitude got from LocationManager but it does not.
I've attempted to use LocationRequest too and that hasn't helped.
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(60000);
locationRequest.setFastestInterval(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult){
if(locationRequest==null){
return;
}
for(Location location : locationResult.getLocations()) {
if (location != null){
userLat=location.getLatitude();
userLng=location.getLongitude();
}
}
}
};
LocationServices.getFusedLocationProviderClient(EventLocator.this).requestLocationUpdates(locationRequest,locationCallback, null);
LocationServices.getFusedLocationProviderClient(EventLocator.this).getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location!=null){
double longitude=location.getLongitude();
double latitude=location.getLatitude();
userLng=longitude;
userLat=latitude;
}
}
});
All the permissions are correct, as I said I've used getLastLocation() to place a marker.
Make sure you added location permission in manifest file
If you are using android os 6 above make sure you have location permission
Make sure you GPS service is enabled in you mobile
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;
}
}
If still not working try to restart your phone and then try again.
You can create interface and implement it in the class where you need to calculate the distance
Usually GPS takes time to warm up. Your initial location reading could be from a cold GPS. In order to get a more accurate reading keep reading results until you get an accuracy reading that works for you.
Keep in mind GPS on a phone is not very accurate and would not be able to get accurate readings inside buildings or if not enough coverage is in your area at the time.
Last know position does not give you your current position, like it says it is the last know position which could have been more than a few minutes ago. Also it could've come from a cell tower reading instead of a GPS reading.
I'm using this code
lateinit var fusedLocationProviderClient: FusedLocationProviderClient
lateinit var latitude : Double
lateinit var longitude : Double
override fun onCreate() {
super.onCreate()
fusedLocationProviderClient = FusedLocationProviderClient(this)
updateLocationTracking()
}
#SuppressLint("MissingPermission")
private fun updateLocationTracking() {
if(PermissionUtility.isPermissionsGranted(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
val request = LocationRequest().apply {
interval = LOCATION_UPDATE_INTERVAL
fastestInterval = FASTEST_LOCATION_INTERVAL
priority = PRIORITY_HIGH_ACCURACY
}
fusedLocationProviderClient.requestLocationUpdates(
request,
locationCallback,
Looper.getMainLooper()
)
}
}
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(result: LocationResult?) {
super.onLocationResult(result)
result?.locations?.let { locations ->
for(location in locations) {
setLocationData(location)
}
}
}
}
private fun setLocationData(location : Location){
latitude = location.latitude
longitude = location.longitude
}
}
So I figured it out when I couldn't use my phone I use for debugging and used my personal phone for testing, went on the activity and the distances were correct.
Messed around with both debug phone settings and using GPS_PROVIDER and NETWORK_PROVIDER and when my phone used just GPS to get location, it got nothing. Other phone can, so think it's safe to say my debug phone's GPS is borked.
It's a old phone that, when I got a new one, I factory reset to use for debugging, as it helped with the backwards compatibility for older phones and smaller screens. I never thought if the actual hardware was faulty too after the reset.
So error was with the phone itself not the app. Guess it goes to show have two devices to test on.

ANdroid: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude() [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am creating a directional application in android . that why i have to get the location from the android device here is my code when i run this code it give me Exception at these line
curlat = location.getLatitude();
curlng = location.getLongitude();
This is whole function
public void newlocation(Context context) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the location provider
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE); // default
// user defines the criteria
criteria.setCostAllowed(false);
// get the best provider depending on the criteria
provider = locationManager.getBestProvider(criteria, false);
// the last known location of this provider
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;
}
Location location = locationManager.getLastKnownLocation(provider);
mylistener = new MyLocationListener();
if (location != null) {
mylistener.onLocationChanged(location);
} else {
// leads to the settings because there is no last known location
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
// location updates: at least 1 meter and 200millsecs change
locationManager.requestLocationUpdates(provider, 200, 1, mylistener);
// String a=""+location.getLatitude();
// Toast.makeText(getApplicationContext(), a, 222).show();
curlat = location.getLatitude();
curlng = location.getLongitude();
Log.d("************", "1111111111111111");
new GetAddressTask(this).execute(location);
}
You are getting null object of location so before access the lat and log make a null point check
if(location!= null){
double latitude = location.getLatitude();
double longitude = location.getLongitude();}

Problems displaying a location and centering the camera on it

I've just had some issues for odd reasons with the CameraUpdateFactory.
So I incorporated this code in an onclickListener on the GpsButton on a navigation fragment:
if (ContextCompat.checkSelfPermission(mapFragment.getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
Log.d("Permission checked", "checkSelfPermission passed with no errors");
map.setMyLocationEnabled(true);
Log.d("Permission checked", "Location Layer implementation successful");
} else {
//Request the Permission
ActivityCompat.requestPermissions(mapFragment.getActivity(), new String[]{
Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
This basically enables the location to be displayed as a blue dot on the map only when the GPS button is pressed. This has been perfectly functional so far.
I also incorporated a method to move the camera to my current location:
public void locateMe() {
LocationManager locationManager = (LocationManager) getActivity().getSystemService(LOCATION_SERVICE); // Getting LocationManager object from System Service LOCATION_SERVICE
Criteria criteria = new Criteria();// Creating a criteria object to retrieve provider
String provider = locationManager.getBestProvider(criteria, true);// Getting the name of the best provider
if (ContextCompat.checkSelfPermission(mapFragment.getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(mapFragment.getActivity(), new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 2);
}
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
double latitude = location.getLatitude(); //Getting latitude of the current location
double longitude = location.getLongitude(); // Getting longitude of the current location
myPosition = new LatLng(latitude, longitude); // Creating a LatLng object for the current location
map.moveCamera(CameraUpdateFactory.newLatLngZoom(myPosition, CAMPUS_DEFAULT_ZOOM_LEVEL));//Camera Update method
}
}
For some reason, this is hit or miss. 3 days ago, it was locking on a position that wasn't where I currently was located while for the past 2 days it worked perfectly. No code was changed whatsoever. Could someone please explain what's going on? Any fixes or suggestions would be appreciated.
This occurs because you are using getLastKnownLocation.
This can be done without starting the provider. Note that this location could be out-of-date, for example if the device was turned off and moved to another location.
If the provider is currently disabled, null is returned.
documentation
You have to use requestLocation updates if you want to retrieve the user's current documentation.
requestLocationUpdates documentation

Categories