Android Geofencing with Google Play 6.5.87

I have no problem with Google Play Services 6.1.71 (because everything works well), but not the same with the new version (6.5.87).

I already know that the LocationClient class is deprecated in the 6.5.87 Google Play Services class, and I have few problems converting the old GeofenceDetection sample ( http://developer.android.com/shareables/training/GeofenceDetection.zip ).

  • The first problem I encountered with the new Play Services, I did not find OnAddGeofencesResultListener and OnRemoveGeofencesResultListener, which I used to handle errors on the console;
  • The second problem (the main problem) is to add a geofence point. When I try to add one request, I get the pending undefined ...

The code I changed:

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 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 geofences = geoFenceEvent.getTriggeringGeofences ();
                 String [] geofenceIds = new String [geofences.size ()];
                 for (int index = 0; index = 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 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 geofences) throws UnsupportedOperationException {

         / *
          * Save the geofences so that they can be sent to Location Services once the
          * connection is available.
          * /
         mCurrentGeofences = (ArrayList) 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);
         }
     }
 } 
+6
source share
2 answers

Check out the samples for the new Google Apps SDK https://github.com/googlesamples/android-play-location

+4
source

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 } } }); 
+2
source

Source: https://habr.com/ru/post/979584/


All Articles