I have no problem with Google Play Services 6.1.71 (because everything works well) but not the same thing with newer version (6.5.87).
I already know LocationClient
class is deprecated in 6.5.87 Google Play Services class and I have little problem with converting old GeofenceDetection sample.
OnAddGeofencesResultListener
and OnRemoveGeofencesResultListener
that I used to handle errors on console;The code that I have modified is:
ReceiveTransitionsIntentService.java
public class ReceiveTransitionsIntentService extends IntentService {
/**
* Sets an identifier for this class' background thread
*/
public ReceiveTransitionsIntentService() {
super("ReceiveTransitionsIntentService");
}
/**
* Handles incoming intents
*
* @param intent The Intent sent by Location Services. This Intent is provided
* to Location Services (inside a PendingIntent) when you call addGeofences()
*/
@Override
protected void onHandleIntent(Intent intent) {
// Create a local broadcast Intent
Intent broadcastIntent = new Intent();
// Give it the category for all intents sent by the Intent Service
broadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES);
GeofencingEvent geoFenceEvent = GeofencingEvent.fromIntent(intent);
// First check for errors
if (geoFenceEvent.hasError()) {
// Get the error code
int errorCode = geoFenceEvent.getErrorCode();
// Get the error message
String errorMessage = LocationServiceErrorMessages.getErrorString(this, errorCode);
// Log the error
Log.e(GeofenceUtils.APPTAG, getString(R.string.geofence_transition_error_detail, errorMessage));
// Set the action and error message for the broadcast intent
broadcastIntent.setAction(GeofenceUtils.ACTION_GEOFENCE_ERROR).putExtra(GeofenceUtils.EXTRA_GEOFENCE_STATUS, errorMessage);
// Broadcast the error *locally* to other components in this app
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
// If there's no error, get the transition type and create a notification
} else {
// Get the type of transition (entry or exit)
int transition = geoFenceEvent.getGeofenceTransition();
// Test that a valid transition was reported
if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER) || (transition == Geofence.GEOFENCE_TRANSITION_EXIT)) {
// Post a notification
List<Geofence> geofences = geoFenceEvent.getTriggeringGeofences();
String[] geofenceIds = new String[geofences.size()];
for (int index = 0; index < geofences.size(); index++) {
geofenceIds[index] = geofences.get(index).getRequestId();
}
String ids = TextUtils.join(GeofenceUtils.GEOFENCE_ID_DELIMITER, geofenceIds);
String transitionType = getTransitionString(transition);
sendNotification(transitionType, ids);
// Log the transition type and a message
Log.d(GeofenceUtils.APPTAG, getString(R.string.geofence_transition_notification_title, transitionType, ids));
Log.d(GeofenceUtils.APPTAG, getString(R.string.geofence_transition_notification_text));
// An invalid transition was reported
} else {
// Always log as an error
Log.e(GeofenceUtils.APPTAG,
getString(R.string.geofence_transition_invalid_type, transition));
}
}
}
/**
* Posts a notification in the notification bar when a transition is detected.
* If the user clicks the notification, control goes to the main Activity.
*
* @param transitionType The type of transition that occurred.
*/
private void sendNotification(String transitionType, String ids) {
// Create an explicit content Intent that starts the main Activity
Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
// Construct a task stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the main Activity to the task stack as the parent
stackBuilder.addParentStack(MainActivity.class);
// Push the content Intent onto the stack
stackBuilder.addNextIntent(notificationIntent);
// Get a PendingIntent containing the entire back stack
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Get a notification builder that's compatible with platform versions >= 4
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Set the notification contents
builder.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(getString(R.string.geofence_transition_notification_title, transitionType, ids))
.setContentText(getString(R.string.geofence_transition_notification_text))
.setContentIntent(notificationPendingIntent);
// Get an instance of the Notification manager
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Issue the notification
mNotificationManager.notify(0, builder.build());
}
/**
* Maps geofence transition types to their human-readable equivalents.
*
* @param transitionType A transition type constant defined in Geofence
* @return A String indicating the type of transition
*/
private String getTransitionString(int transitionType) {
switch (transitionType) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
return getString(R.string.geofence_transition_entered);
case Geofence.GEOFENCE_TRANSITION_EXIT:
return getString(R.string.geofence_transition_exited);
default:
return getString(R.string.geofence_transition_unknown);
}
}
}
GeofenceRequester.java
public class GeofenceRequester implements
ConnectionCallbacks,
OnConnectionFailedListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
// Storage for a reference to the calling client
private final Activity mActivity;
// Stores the PendingIntent used to send geofence transitions back to the app
private PendingIntent mGeofencePendingIntent;
// Stores the current list of geofences
private ArrayList<Geofence> mCurrentGeofences;
// Stores the current instantiation of the location client
private GoogleApiClient mGoogleApiClient;
/*
* Flag that indicates whether an add or remove request is underway. Check this
* flag before attempting to start a new request.
*/
private boolean mInProgress;
public GeofenceRequester(Activity activityContext) {
// Save the context
mActivity = activityContext;
// Initialize the globals to null
mGeofencePendingIntent = null;
mGoogleApiClient = null;
mInProgress = false;
}
/**
* Set the "in progress" flag from a caller. This allows callers to re-set a
* request that failed but was later fixed.
*
* @param flag Turn the in progress flag on or off.
*/
public void setInProgressFlag(boolean flag) {
// Set the "In Progress" flag.
mInProgress = flag;
}
/**
* Get the current in progress status.
*
* @return The current value of the in progress flag.
*/
public boolean getInProgressFlag() {
return mInProgress;
}
/**
* Returns the current PendingIntent to the caller.
*
* @return The PendingIntent used to create the current set of geofences
*/
public PendingIntent getRequestPendingIntent() {
return createRequestPendingIntent();
}
/**
* Start adding geofences. Save the geofences, then start adding them by requesting a
* connection
*
* @param geofences A List of one or more geofences to add
*/
public void addGeofences(List<Geofence> geofences) throws UnsupportedOperationException {
/*
* Save the geofences so that they can be sent to Location Services once the
* connection is available.
*/
mCurrentGeofences = (ArrayList<Geofence>) geofences;
// If a request is not already in progress
if (!mInProgress) {
// Toggle the flag and continue
mInProgress = true;
// Request a connection to Location Services
requestConnection();
// If a request is in progress
} else {
// Throw an exception and stop the request
throw new UnsupportedOperationException();
}
}
/**
* Request a connection to Location Services. This call returns immediately,
* but the request is not complete until onConnected() or onConnectionFailure() is called.
*/
private void requestConnection() {
getLocationClient().connect();
}
/**
* Get the current location client, or create a new one if necessary.
*
* @return A LocationClient object
*/
private GoogleApiClient getLocationClient() {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
return mGoogleApiClient;
}
/**
* Once the connection is available, send a request to add the Geofences
*/
private void continueAddGeofences() {
// Get a PendingIntent that Location Services issues when a geofence transition occurs
mGeofencePendingIntent = createRequestPendingIntent();
// Send a request to add the current geofences
LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, mCurrentGeofences, mGeofencePendingIntent);
}
/**
* Get a location client and disconnect from Location Services
*/
private void requestDisconnection() {
// A request is no longer in progress
mInProgress = false;
getLocationClient().disconnect();
}
/*
* Called by Location Services once the location client is connected.
*
* Continue by adding the requested geofences.
*/
@Override
public void onConnected(Bundle arg0) {
// If debugging, log the connection
Log.d(GeofenceUtils.APPTAG, mActivity.getString(R.string.connected));
// Continue adding the geofences
continueAddGeofences();
}
@Override
public void onConnectionSuspended(int i) {
}
/*
* Called by Location Services once the location client is disconnected.
*/
@Override
public void onDisconnected() {
// Turn off the request flag
mInProgress = false;
// In debug mode, log the disconnection
Log.d(GeofenceUtils.APPTAG, mActivity.getString(R.string.disconnected));
// Destroy the current location client
mGoogleApiClient = null;
}
/**
* Get a PendingIntent to send with the request to add Geofences. Location Services issues
* the Intent inside this PendingIntent whenever a geofence transition occurs for the current
* list of geofences.
*
* @return A PendingIntent for the IntentService that handles geofence transitions.
*/
private PendingIntent createRequestPendingIntent() {
// If the PendingIntent already exists
if (null != mGeofencePendingIntent) {
// Return the existing intent
return mGeofencePendingIntent;
// If no PendingIntent exists
} else {
// Create an Intent pointing to the IntentService
Intent intent = new Intent(mActivity, ReceiveTransitionsIntentService.class);
/*
* Return a PendingIntent to start the IntentService.
* Always create a PendingIntent sent to Location Services
* with FLAG_UPDATE_CURRENT, so that sending the PendingIntent
* again updates the original. Otherwise, Location Services
* can't match the PendingIntent to requests made with it.
*/
return PendingIntent.getService(
mActivity,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
}
/*
* Implementation of OnConnectionFailedListener.onConnectionFailed
* If a connection or disconnection request fails, report the error
* connectionResult is passed in from Location Services
*/
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Turn off the request flag
mInProgress = false;
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(mActivity,
GeofenceUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (SendIntentException e) {
// Log the error
e.printStackTrace();
}
/*
* If no resolution is available, put the error code in
* an error Intent and broadcast it back to the main Activity.
* The Activity then displays an error dialog.
* is out of date.
*/
} else {
Intent errorBroadcastIntent = new Intent(GeofenceUtils.ACTION_CONNECTION_ERROR);
errorBroadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES)
.putExtra(GeofenceUtils.EXTRA_CONNECTION_ERROR_CODE,
connectionResult.getErrorCode());
LocalBroadcastManager.getInstance(mActivity).sendBroadcast(errorBroadcastIntent);
}
}
}
To replace OnAddGeofencesResultListener
use ResultCallback
LocationServices.GeofencingApi
.addGeofences(mGoogleApiClient, mCurrentGeofences, mGeofencePendingIntent)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
if (status.isSuccess()) {
// Success
}
}
});
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