0

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.

  • 1
    Does this answer your question? [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – a_local_nobody Apr 01 '21 at 12:22
  • Basically it's because of some possible reasons like `task` may be null or `task.getResult()` can be null, try to find out whats the problem for your case – Vivek Thummar Apr 01 '21 at 12:23
  • Welcome to Stack Overflow! I would recommend [edit]ing your question a bit to make it more specific to your problem. The issue isn't that you're getting a NPE, but that your location provider is giving you a null location. Also take a look at how to produce a [mre], posting all your irrelevant code isn't very helpful for anyone answering. – Henry Twist Apr 01 '21 at 12:32
  • Ah, I understand what exactly a NullPointerException is, I'm just not certain why the location object is null, thx for the help though. So it's the actual Task object which is null then...hmm, I'll have a look, thx! – NigelKnight Apr 01 '21 at 12:33
  • Edited it to include less irrelevant code. I hope the question is a bit more clear as well – NigelKnight Apr 01 '21 at 12:40

1 Answers1

0

Which device do you use? If you use an emulator, make sure to use a system image with the Google APIs or Google Play Store installed on

enter image description here

  • I'm using a Samsung Galaxy S7. As an emulator won't have an actual gps signal, it should not give me a location at all. However, my S7 should give me a location instead of the NPE. – NigelKnight Apr 01 '21 at 14:07