In my code I have been trying to get the location coordinates of the user using getLastKnownLocation() This method should only be called when mLocationPermissionGranted is set to true. After getting the location coordinates I store them in an object with the method createLocation which takes 2 doubles as parameters. However, before I can reach the activity in which my map is created I get the error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.recipes, PID: 18666
java.lang.NullPointerException: Attempt to invoke virtual method 'double
android.location.Location.getLatitude()' on a null object reference
at com.example.recipes.views.activities.discovery.DiscoveryWorld$2.onComplete(DiscoveryWorld.java:187)
at com.google.android.gms.tasks.zzj.run(com.google.android.gms:play-services-tasks@@17.2.0:4)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
I have added all necessary requirements in the AndroidManifest.xml, including the permissions + API key.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
This is the part of the class which I am running to get the user location:
package com.example.recipes.views.activities.discovery;
//Whole bunch of imports
/**
* This Class will open a map for the user and displays recipes uploaded by other users on the map.
* The location at which users posted their recipes will be saved in the database.
* By clicking on a marker of a recipe the user will receive more details about said recipe
*/
public class DiscoveryWorld extends AppCompatActivity implements OnMapReadyCallback {
//To be used for the latitude and longitude coordinates
double lat_test;
double lon_test;
public static UserLocation mulocation = new UserLocation();
private MapView mMapView;
private FusedLocationProviderClient mFusedLocationProviderClient;
@Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_discovery_world);
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
}
//Get user location
public void getLastKnownLocation () {
System.out.println("getLastKnownLocation was called");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
System.out.println("failed");
return;
}
mFusedLocationProviderClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful()) {
Location location = task.getResult();
lat_test = location.getLatitude(); // <- gets NullPointerException error
lon_test = location.getLongitude(); // <- gets NullPointerException error
System.out.println(lon_test + "and" + lat_test);
// lat_test = 25;
// lon_test = 35;
System.out.println("hello!!!");
createLocation(lat_test, lon_test);
}
}
});
}
@Override
public void onRequestPermissionsResult ( int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults){
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
getLastKnownLocation();
}
}
}
System.out.println("LocationPerms: " + mLocationPermissionGranted);
}
@Override
protected void onActivityResult ( int requestCode, int resultCode, Intent data){
System.out.println("LocationPerms: " + mLocationPermissionGranted);
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case PERMISSIONS_REQUEST_ENABLE_GPS: {
if (mLocationPermissionGranted) {
getLastKnownLocation();
} else {
getLocationPermission();
}
}
}
}
My question is: Why is the Task object in getLastKnownLocation() null? My device Location is turned on, and the app has access to my device's location. Apologies if my post is a bit messy, as this is my first post on SO. If I need to clarify some lines or assumptions I'd be happy to oblige
Edited to include less irrelevant code*
Latest Edit: It seems that the getLastKnownLocation only returns the location other applications have read. Other than that getLastKnownLocation is relatively unstable. I recommend for anyone who has a similar problem to have a look at: https://developer.android.com/training/location/request-updates and/or https://www.youtube.com/watch?v=4eWoXPSpA5Y
The page and video will show you how to request constant updates on the user's location, which is a lot more reliable.