Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Samsung Note 2 can't reach onLocationChanged()

It works on most devices except Galaxy Note 2. It connects to Google Client, but can't reach onLocationChanged() that implements LocationListener. Anyone has any idea what it causes and why only on this device?

@Override
public void onLocationChanged(Location location) {

    mLastLocation = location;

    if (mLastLocation != null) {
        lat = mLastLocation.getLatitude();
        lng = mLastLocation.getLongitude();

        Toast.makeText(getApplicationContext(), String.valueOf(lat) + "/" + String.valueOf(lng), Toast.LENGTH_LONG).show();

        serverUrl = "http://(my server)/offers?lat=" + String.valueOf(mLastLocation.getLatitude())
                            + "&lng=" + String.valueOf(mLastLocation.getLongitude()) + "&distance=1";
        // save
        makeTag(serverUrl);

        // after getting location data - unregister listener
                    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mFusedLocationCallback);
        new GetBackgroundUpdate().execute();
    } else {
        // get data from server and update GridView
        new GetBackgroundUpdate().execute();
        Toast.makeText(getApplicationContext(), R.string.no_location_detected, Toast.LENGTH_LONG).show();

     }
/**
Location methods
*/
protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
}

/**
* Runs when a GoogleApiClient object successfully connects.
*/
@Override
public void onConnected(Bundle connectionHint) {
    // Provides a simple way of getting a device's location and is well suited for
    // applications that do not require a fine-grained location and that do not need location
    // updates. Gets the best and most recent location currently available, which may be null
    // in rare cases when a location is not available.
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(1000);
    mLocationRequest.setFastestInterval(500);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mFusedLocationCallback);

}

@Override
public void onConnectionFailed(ConnectionResult result) {
    // Refer to the javadoc for ConnectionResult to see what error codes might be returned in
    // onConnectionFailed.
    Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());

    if (mResolvingError) {
        // Already attempting to resolve an error.
        return;
    } else if (result.hasResolution()) {
        try {
            mResolvingError = true;
            result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
        } catch (IntentSender.SendIntentException e) {
            // There was an error with the resolution intent. Try again.
            mGoogleApiClient.connect();
        }
    } else {
        // Show dialog using GooglePlayServicesUtil.getErrorDialog()
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(String.valueOf(result.getErrorCode()))
                    .setCancelable(false)
                    .setNegativeButton("Ok", new DialogInterface.OnClickListener() {
                        public void onClick(final DialogInterface dialog, final int id) {
                            dialog.cancel();
                        }
                    });
        final AlertDialog alert = builder.create();
        alert.show();
        mResolvingError = true;
    }

    //new GetBackgroundUpdate().execute();
}

@Override
public void onConnectionSuspended(int cause) {
    // The connection to Google Play services was lost for some reason. We call connect() to
    // attempt to re-establish the connection.
    Log.i(TAG, "Connection suspended");
    mGoogleApiClient.connect();
}

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

@Override
protected void onStop() {
    super.onStop();
    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
    }
}
like image 267
jean d'arme Avatar asked May 05 '15 14:05

jean d'arme


1 Answers

Edit: From the line in your comment where the NullPointerException is happening, just ensure that mLastLocation is not null.

if (mLastLocation != null){
    address = server + String.valueOf(mLastLocation.getLatitude()) + "&lng=" + String.valueOf(mLastLocation.getLongitude()) + "&distance=" + distance;
} 

Another thing to note is that you should always ensure that mGoogleApiClient is not null and connected before using it.

if (mGoogleApiClient != null && mGoogleApiClient.isConnected()){
  //..... use mGoogleApiClient.....
}

See documentation here

You should also add a check to see if Google Play Services are available, as sometimes the version available on the device is below the version that you compile your app with. There is a dialog that you can show if that is the case.

Below is how to check if Google Play Services are available.

private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }
    }

Note that getLastLocation() has a high tendency to return null, so a good approach would be to register a location listener if you get a null value from the first call to getLastLocation().
See this post: LocationClient getLastLocation() return null

Here is a guide for how to register a LocationListener:

Creating a listener:

LocationCallback mFusedLocationCallback = new LocationCallback();

Class definition:

private class LocationCallback implements LocationListener {

        public LocationCallback() {

        }

        @Override
        public void onLocationChanged(Location location) {

                 mLastLocation = location;
                 lat = String.valueOf(mLastLocation.getLatitude());
                 lng = String.valueOf(mLastLocation.getLongitude());


             }
    };

Then just register the LocationListener :

  mLocationRequest = new LocationRequest();
  mLocationRequest.setInterval(minTime);
  mLocationRequest.setFastestInterval(fastestTime);
  mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
  mLocationRequest.setSmallestDisplacement(distanceThreshold);

 LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mFusedLocationCallback);

Edit: You should wait for the API to be connected before you register for location callbacks, it should be something like this:

/**
 * Runs when a GoogleApiClient object successfully connects.
 */
@Override
public void onConnected(Bundle connectionHint) {
    // Provides a simple way of getting a device's location and is well suited for
    // applications that do not require a fine-grained location and that do not need location
    // updates. Gets the best and most recent location currently available, which may be null
    // in rare cases when a location is not available.
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if (mLastLocation != null) {
        lat = String.valueOf(mLastLocation.getLatitude());
        lng = String.valueOf(mLastLocation.getLongitude());
    } else {
        Toast.makeText(this, R.string.no_location_detected, Toast.LENGTH_LONG).show();
    }


     mLocationRequest = new LocationRequest();
     mLocationRequest.setInterval(1000);
     mLocationRequest.setFastestInterval(500);
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mFusedLocationCallback);
}

Documentation: for requestLocationUpdates.... and LocationRequest.

One last thing, make sure that you have this in your AndroidManifest.xml inside the application tag:

  <meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />
like image 151
Daniel Nugent Avatar answered Sep 19 '22 10:09

Daniel Nugent