title: Awareness API delays activity callbacks significantly
body: <p>I've created a class and a BroadcastReceiver to get callbacks from the awareness api for when walking or running ends.
  I wasn't getting timely callbacks and at first thought it was because I had registered a 'stopping' callback, but then after setting my phone down for a bit, I did get several callbacks! But this was far far from the time I'd stopped walking. At least 5 minutes after stopping.
  Sometimes I don't get callbacks even when the Google Fit app records activity.</p>
  
  <p>Since I have gotten callbacks at least a few times I know the registration is ok. Why are the calls this delayed and sometimes missing?</p>
  
  <p>For background reference, I'm registering these callbacks in the onStart on the main activty, i.e initiateAwareness is called at that time, within the onstart on an activity. And i never unregister them.
  I don't intend to use it this way in production, it was just for testing. Plus my inital attempt of registering the fences with an application context failed.</p>
  
  <p>Here's the helper class I made to set up the registration of the google client and fences.</p>
  
  <pre><code>public class AwarenessHelper {
  
  
  public static final String WALKING_ENDED_FENCE = "walkingEndedKey";
  public static final String RUNNING_ENDED_FENCE = "runningEndedKey";
  public static final String TYPE_2_WALKING = "duringWalkingKey";
  public static final String TYPE_2_RUNNING = "duringRunningKey";
  
  private String tag = AwarenessHelper.class.getSimpleName();
  
  public void initiateAwareness(final Activity context)
  {
      final GoogleApiClient googleApiClient = buildClient(context);
      Log.d(tag, "Initiating blocking connect");
      googleApiClient.registerConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
          @Override
          public void onConnected(@Nullable Bundle bundle) {
              if ( googleApiClient.isConnected() )
              {
                  Log.d(tag, "Client connected, initiating awareness fence registration");
                  registerAwarenessFences(context, googleApiClient);
              }
              else
              {
                  Log.d(tag, "Couldn't connect");
              }
  
          }
  
          @Override
          public void onConnectionSuspended(int i) {
  
          }
  
  
      });
  
      googleApiClient.connect();
  }
  
  private void registerAwarenessFences(Context context, GoogleApiClient mGoogleApiClient) {
      Awareness.FenceApi.updateFences(
              mGoogleApiClient,
              new FenceUpdateRequest.Builder()
                      .addFence(WALKING_ENDED_FENCE, DetectedActivityFence.stopping(DetectedActivityFence.WALKING), getBroadcastPendingIntent(context))
                      .addFence(RUNNING_ENDED_FENCE, DetectedActivityFence.stopping(DetectedActivityFence.RUNNING), getBroadcastPendingIntent(context))
                      .addFence(TYPE_2_WALKING, DetectedActivityFence.during(DetectedActivityFence.WALKING), getBroadcastPendingIntent(context))
                      .addFence(TYPE_2_RUNNING, DetectedActivityFence.stopping(DetectedActivityFence.RUNNING), getBroadcastPendingIntent(context))
                      .build())
              .setResultCallback(new ResultCallback&lt;Status&gt;() {
                  @Override
                  public void onResult(@NonNull Status status) {
                      if (status.isSuccess()) {
                          Log.i(tag, "Fence was successfully registered.");
                      } else {
                          Log.e(tag, "Fence could not be registered: " + status);
                      }
                  }
              });
  }
  
  private GoogleApiClient buildClient(final Activity activity)
  {
      GoogleApiClient client = new GoogleApiClient.Builder(activity)
              .addApi(Awareness.API)
              .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                  @Override
                  public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                      if ( connectionResult.hasResolution() &amp;&amp; connectionResult.getErrorCode() == CommonStatusCodes.SIGN_IN_REQUIRED )
                      {
                          try {
                              connectionResult.startResolutionForResult(activity, GOOGLE_FIT_AUTHORIZATION_REQUEST_CODE);
                          } catch (IntentSender.SendIntentException e) {
                              e.printStackTrace();
                          }
                      }
                  }
              })
              .build();
      return client;
  }
  
  private PendingIntent getBroadcastPendingIntent(Context context)
  {
      Intent intent = new Intent(AWARENESS_BROADCAST_ACTION);
      PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
  
      return pendingIntent;
  }
  }
  </code></pre>
  
  <p>Here's the BroadcastReceiver:</p>
  
  <pre><code>public class AwarenessHelper {
  
  
      public static final String WALKING_ENDED_FENCE = "walkingEndedKey";
      public static final String RUNNING_ENDED_FENCE = "runningEndedKey";
      public static final String TYPE_2_WALKING = "duringWalkingKey";
      public static final String TYPE_2_RUNNING = "duringRunningKey";
  
      private String tag = AwarenessHelper.class.getSimpleName();
  
      public void initiateAwareness(final Activity context)
      {
          final GoogleApiClient googleApiClient = buildClient(context);
          Log.d(tag, "Initiating blocking connect");
          googleApiClient.registerConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
              @Override
              public void onConnected(@Nullable Bundle bundle) {
                  if ( googleApiClient.isConnected() )
                  {
                      Log.d(tag, "Client connected, initiating awareness fence registration");
                      registerAwarenessFences(context, googleApiClient);
                  }
                  else
                  {
                      Log.d(tag, "Couldn't connect");
                  }
  
              }
  
              @Override
              public void onConnectionSuspended(int i) {
  
              }
  
  
          });
  
          googleApiClient.connect();
      }
  
      private void registerAwarenessFences(Context context, GoogleApiClient mGoogleApiClient) {
          Awareness.FenceApi.updateFences(
                  mGoogleApiClient,
                  new FenceUpdateRequest.Builder()
                          .addFence(WALKING_ENDED_FENCE, DetectedActivityFence.stopping(DetectedActivityFence.WALKING), getBroadcastPendingIntent(context))
                          .addFence(RUNNING_ENDED_FENCE, DetectedActivityFence.stopping(DetectedActivityFence.RUNNING), getBroadcastPendingIntent(context))
                          .addFence(TYPE_2_WALKING, DetectedActivityFence.during(DetectedActivityFence.WALKING), getBroadcastPendingIntent(context))
                          .addFence(TYPE_2_RUNNING, DetectedActivityFence.stopping(DetectedActivityFence.RUNNING), getBroadcastPendingIntent(context))
                          .build())
                  .setResultCallback(new ResultCallback&lt;Status&gt;() {
                      @Override
                      public void onResult(@NonNull Status status) {
                          if (status.isSuccess()) {
                              Log.i(tag, "Fence was successfully registered.");
                          } else {
                              Log.e(tag, "Fence could not be registered: " + status);
                          }
                      }
                  });
      }
  
      private GoogleApiClient buildClient(final Activity activity)
      {
          GoogleApiClient client = new GoogleApiClient.Builder(activity)
                  .addApi(Awareness.API)
                  .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                      @Override
                      public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                          if ( connectionResult.hasResolution() &amp;&amp; connectionResult.getErrorCode() == CommonStatusCodes.SIGN_IN_REQUIRED )
                          {
                              try {
                                  connectionResult.startResolutionForResult(activity, GOOGLE_FIT_AUTHORIZATION_REQUEST_CODE);
                              } catch (IntentSender.SendIntentException e) {
                                  e.printStackTrace();
                              }
                          }
                      }
                  })
                  .build();
          return client;
      }
  
      private PendingIntent getBroadcastPendingIntent(Context context)
      {
          Intent intent = new Intent(AWARENESS_BROADCAST_ACTION);
          PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
  
          return pendingIntent;
      }
  }
  </code></pre>
  
  <p>I get the notifications, but after a massive delay and sometimes not at all.
  I am starting the Activity many times, so perhaps the fences are being registered over and over? Is that a relevant fact?
  Also is a service or broadcast receiver context appropriate for the initialisation of awareness clients and fences?</p>