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();
}
}
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" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With