-1

First of all, I'd like to apologize if I'm not making myself very clear, as English is not my first language + this is actually the first android app that I'm writing, so I don't know the terms/names for things as well.

The problem I'm having is that when I have bad GPS and/or network connection, my app crashes as soon as it can't get the current location which needed for the whole program to work (might crash because it can't connect to google services?). I don't know specifically why that's happening as I don't have bad connection at the moment, which means I debug the program and check exactly why it's crashing, but I will try to include as much of the methods that use location as needed.

First I initialize the variable:

private LocationRequest mLocationRequest;

In onCreate() I create the following objects:

mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

    mLocationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setSmallestDisplacement(1)
            .setInterval(2 * 1000)
            .setFastestInterval(1000);

Then later on I'm overriding onConnected() :

@Override
public void onConnected(Bundle bundle) {
    Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    handleNewLocation(location);
}

onConnectionFailed() :

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    if (connectionResult.hasResolution()) {
        try {
            connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
        } catch (IntentSender.SendIntentException e) {
            e.printStackTrace();
        }
    } else {
        Log.i(TAG, "Connection has failed, code: " + connectionResult.getErrorCode());
    }
}

And here's the function handleNewLocation() using the location:

private void handleNewLocation(Location location) {
    Log.d(TAG, location.toString());
    double currentLatitude = location.getLatitude();
    double currentLongitude = location.getLongitude();

This is from the crash log:

05-24 14:08:10.312 22251 22251 E AndroidRuntime: FATAL EXCEPTION: main
05-24 14:08:10.312 22251 22251 E AndroidRuntime: Process: xx.xx.xx.checkpoints, PID: 22251
05-24 14:08:10.312 22251 22251 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.location.Location.toString()' on a null object reference
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at xx.xx.xx.checkpoints.MapsActivity.handleNewLocation(MapsActivity.java:400)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at xx.xx.xx.checkpoints.MapsActivity.onConnected(MapsActivity.java:364)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.google.android.gms.common.internal.zzj.zzg(Unknown Source)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.google.android.gms.common.api.zze.zzmH(Unknown Source)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.google.android.gms.common.api.zze.onConnected(Unknown Source)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.google.android.gms.common.api.zzg$2.onConnected(Unknown Source)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.google.android.gms.common.internal.zzi$zzg.zznO(Unknown Source)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.google.android.gms.common.internal.zzi$zza.zzc(Unknown Source)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.google.android.gms.common.internal.zzi$zza.zzr(Unknown Source)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.google.android.gms.common.internal.zzi$zzc.zznQ(Unknown Source)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.google.android.gms.common.internal.zzi$zzb.handleMessage(Unknown Source)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:102)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:154)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:6724)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
05-24 14:08:10.312 22251 22251 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

What should I do to improve this? As in what could be the fix for the crashes? How could I check if the location has been set, and if it hasn't, wait until the location is found before continuing with the program? Just for clarification, I'm using Maps v1.

jit
  • 1
  • 5

4 Answers4

0

I guess you have to check if this method LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); returning null, i suggest you check location variable before getting data from it.

private void handleNewLocation(Location location) {
    if(location ==null)
        return;
    Log.d(TAG, location.toString());
    double currentLatitude = location.getLatitude();
    double currentLongitude = location.getLongitude();

hope this works

Edit: The fused Location Provider will only maintain background location if at least one client is connected to it. Now just turning on the location service will not guarantee to store the last known location.

refer to: this answer

dali
  • 46
  • 1
  • 7
0

First, you need to check if the location is not null and then extract the latitude and longitude and if the location is null then you need to request for the location update.

protected void startLocationUpdates() { 
LocationServices.FusedLocationApi.requestLocationUpdates( 
        mGoogleApiClient, mLocationRequest, this);} 

and once the location is available then the callback method will be called

 @Override 
public void onLocationChanged(Location location) { 
    mCurrentLocation = location; 
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date()); 
    updateUI(); 
} 

check the official android link for more information

0

You have not connected the GoogleApiclient. Copy paste this in your activity.

    @Override
protected void onStart() {
    mGoogleApiClient.connect();

    super.onStart();

}
protected void onStop() {
    mGoogleApiClient.disconnect();
    super.onStop();
}

Hope this helps. Happy coding

Nyagaka Enock
  • 444
  • 1
  • 10
  • 20
  • I will try it out but I dont think this is the case because the app works if I have okay connection (via 4G/GPS), it just crashes when I have bad connection and it doesn't fetch the location immediately. – jit May 24 '17 at 13:02
0

Fiddled around for a while and seemed like this is the solution, even when the app doesn't connect to the services/GPS/network etc right away it will check if the "location" variable is null, and if it is it will try to get the location information same way as before, until it gets it.

public void onConnected(Bundle bundle) {
    Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    while(location == null) {
        location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }
    handleNewLocation(location);
}
jit
  • 1
  • 5