NullpointerException when calling getSystemService

2019-06-23 17:24发布

问题:

I am trying to create a background service that updates the current gps position. I am getting a NullPointerException at line LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

HomeActivity launches a service

startService(new Intent(getApplicationContext(), ForHire.class));

Service (ForHire) creates a TimerTask Updates

public class ForHire extends Service {

...
private Timer getUpdatesNow = new Timer();
private Updates updates = new Updates(getUpdatesNow);

@Override
public void onCreate() {
    ...
    getUpdatesNow.schedule(updates, God.KM20TIME);
    Log.v("Taxeeta", "Notification created");
}

    private class Updates extends TimerTask implements LocationListener {
    private Timer getUpdatesNow;

    public Updates(Timer newGetUpdatesNow) {
        super();
        getUpdatesNow = newGetUpdatesNow;
        LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                God.KM20TIME, God.KM20DISTANCE, (LocationListener) this);
    }
    public void run() {
        ...
        //do some cleanup
    }
            @Override
    public void onLocationChanged(Location location) {
        Log.v("Taxeeta", "Location changed");
        // do a update of the current location.
    }

The first issue is that I get that NullPointerException. Second issue is that onLocationChanged is never called if I comment out LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, God.KM20TIME, God.KM20DISTANCE, (LocationListener) this); these 2 lines.

My Manifest

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application ...>
   ...
   <uses-library android:name="com.google.android.maps" />
</application>

What am I missing here ?

Edit : Values of KM20TIME = 5000 (5seconds), and KM20DISTANCE = 1 (1meter). Apart from the fix's below, I walked out of my house, got GPS enabled and walked from one corner of my balcony to the other. I noticed that my gps (LSB) changed as I walked from one corner to the other every 5 seconds.

回答1:

The earliest you can call new Updates(getUpdatesNow); is inside your Service's onCreate() method. The simple reason is that getSystemService() requires a valid Context which doesn't exist before entering onCreate().

Try:

private Timer getUpdatesNow;
private Updates updates;

@Override
public void onCreate() {
    ...
    getUpdatesNow = new Timer();
    updates = new Updates(getUpdatesNow);


回答2:

// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

// Define a listener that responds to location updates
Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

if (location != null) {
    Toast.makeText(getBaseContext(),
                            "Last Location is found..",
                            Toast.LENGTH_LONG).show();  
} else {

    Toast.makeText(getBaseContext(),
                            "Last Location is not found..",
                            Toast.LENGTH_LONG).show();
}
LocationListener locationListener = new LocationListener() {
public void onStatusChanged(String provider,
    int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
    Toast.makeText(getApplicationContext(),
        "Gps Enabled", Toast.LENGTH_SHORT).show();
}
public void onProviderDisabled(String provider) {
    Toast.makeText(getApplicationContext(),
        "Gps Disabled", Toast.LENGTH_SHORT).show();
}

@Override
public void onLocationChanged(Location location) {
    Log.i("geolocation",
        "lat is : " + location.getLatitude()
        + " and " + location.getLongitude()
        + "");
    Toast.makeText(getBaseContext(),
    "Location is Changed..", Toast.LENGTH_LONG)
        .show();
}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0,
locationListener);


回答3:

@Override
public void onCreate() {
     new Updates(getUpdatesNow);
    ...
    getUpdatesNow.schedule(updates, God.KM20TIME);
    Log.v("Taxeeta", "Notification created");
}