GoogleApiClient null pointer exception

I am trying to learn android development and now I am developing a fluent location service application.

I have a RunFragment.java class when I want to put a GoogleMap fragment, Textviews with latitude and longitude and some other widgets. First of all, I want to connect to GoogleApiClient, and I created a new class that will do all this work and leave RunFragment.java clear. (Is this a good idea ??) When I try to run my application I got this error:

     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Looper android.content.Context.getMainLooper()' on a null object reference
        at com.google.android.gms.common.api.GoogleApiClient$Builder.<init>(Unknown Source)
        at com.runtheworld.roman.runtheworld.GoogleAPI.buildGoogleApiClient(GoogleAPI.java:28)
        at com.runtheworld.roman.runtheworld.RunFragment.onCreate(RunFragment.java:39)
        at android.app.Fragment.performCreate(Fragment.java:2031)

      

There are corresponding classes:

RunFragment.java

package com.runtheworld.roman.runtheworld;

import android.app.Fragment;
import android.os.Bundle;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;



public class RunFragment extends Fragment  {

private static View view;

// TextViews
TextView lat,lon;

// GoogleApi
private GoogleAPI mGoogleApiClient = new GoogleAPI(getActivity());



// Default Constructor
public RunFragment() {
}


@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    mGoogleApiClient.buildGoogleApiClient();
}
@Override
public void onStart(){
    super.onStart();
    mGoogleApiClient.Connect();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (view != null) {
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null)
            parent.removeView(view);
    }
    try {
        view = inflater.inflate(R.layout.run_fragment, container, false);
    } catch (InflateException e) {
        // Map already created
    }

    lat = (TextView)view.findViewById(R.id.lat);
    lon = (TextView)view.findViewById(R.id.lon);
    lat.setText(String.valueOf(mGoogleApiClient.getLat()));
    lon.setText(String.valueOf(mGoogleApiClient.getLon()));


    return view;
}




}

      

GoogleAPI.java

package com.runtheworld.roman.runtheworld;


import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;

public class GoogleAPI  implements GoogleApiClient.ConnectionCallbacks,    GoogleApiClient.OnConnectionFailedListener {

private Context context;
private GoogleApiClient mGoogleApiClient;
private boolean isConnected;
// Location
Location mLastLocation;

public GoogleAPI(Context c) {
    context = c;
}


protected synchronized void buildGoogleApiClient() {
    Log.d("MYTAG", "BUILDING GOOGLE API");
    mGoogleApiClient = new GoogleApiClient.Builder(context)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}

public boolean Connect(){
    if (!mGoogleApiClient.isConnected())
        mGoogleApiClient.connect();
    else
    Log.d("MYTAG","GoogleApiClient is already connected!");
    return isConnected;
}

@Override
public void onConnected(Bundle bundle) {
    Log.d("MYTAG", "GOOGLE API CONNECTED!");
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
    if (mLastLocation != null) {
    }
}

public double getLat(){
    return mLastLocation.getLatitude();
}
public double getLon(){
    return mLastLocation.getLongitude();
}
@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

}

      

Can anyone please help?

+3


source to share


1 answer


It looks like your original problem was fixed in the comments, this is how you can accomplish the functionality.

First, to fix NPE, make sure it is mLocation

not null before referencing it:

public double getLat(){
    double retVal = 0d;
    if (mLastLocation != null){
       retVal = mLastLocation.getLatitude();
    }
    return retVal;
}
public double getLon(){
    double retVal = 0d;
    if (mLastLocation != null){
       retVal = mLastLocation.getLongitude();
    }
    return retVal;
}

      

The next problem is that it getLastLocation()

has a high tendency to return null.

The best way to get around this is to register a location receiver.

Announce GoogleAPI

as location receiver:



public class GoogleAPI  implements GoogleApiClient.ConnectionCallbacks,    GoogleApiClient.OnConnectionFailedListener, LocationListener{

private Context context;
private GoogleApiClient mGoogleApiClient;
private boolean isConnected;

      

Then, in the register a listener onConnected()

(see. Documentation : how to set values for minTime

, fastestTime

, and distanceThreshold

):

        @Override
        public void onConnected(Bundle bundle) {
            Log.d("MYTAG", "GOOGLE API CONNECTED!");
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                    mGoogleApiClient);
            if (mLastLocation == null) {
               mLocationRequest = new LocationRequest();
               mLocationRequest.setInterval(minTime);
               mLocationRequest.setFastestInterval(fastestTime);
                                 mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
              mLocationRequest.setSmallestDisplacement(distanceThreshold);
              LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            }

        }

      

Then add the modified location callback:

 @Override
    public void onLocationChanged(Location location) {

             mLastLocation = location;

     }

      

+2


source







All Articles