No confirmation when writeProximityUuidMajorMinor completes

On beacons with firmware A3.0.1, updating UUIDMajorMinor values does work successfully but then the onSuccess of the BeaconConnection.WriteCallback isn’t fired.

The app continually waits with no response from the Android SDK.

I can restart the Ranging activity in my app and confirm that the values of the beacon in question were updated, but without the callback informing when the update is complete, I’m left having to assume it worked and run the “success” message on a timer.

Is there any information I can provide to better aid in resolving this?

Here is the code bellow. I have the BeaconConnection in its own class.
The bcClient is an in interface back into the Activity that requested the update.

try
{
   beaconConnection.writeProximityUuidMajorMinor(uuidToSet, majorToSet, minorToSet, new BeaconConnection.WriteCallback()
   {
      @Override
      public void onSuccess()
      {
         beaconConnection.close();

         if (bcClient != null)
            bcClient.BeaconValuesUpdateSucceeded();//Step 4 - alert client

      }

      @Override
      public void onError(EstimoteDeviceException e)
      {
         beaconConnection.close();

         if (bcClient != null)
            bcClient.BeaconValuesUpdateFailed(EBeaconConnectorClient.UpdateErrors.Other);
      }
   });
}
catch (EstimoteException ex)
{
   beaconConnection.close();

   if (bcClient != null)
      bcClient.BluetoothError(ex.getMessage());
}

We have updated our SDK to v0.7 which makes significant changes how to change beacon’s settings.

Please change your code to following and it will work:

// Before
connection.writeMajor(newMajor, callback);
connection.writeMinor(newMinor, callback);

// After: reading
connection.minor().get()
connection.major().get()

// After: writing in batch
connection.edit()
  .set(connection.proximityUuid(), newUuid)
  .set(connection.major(), newMajor)
  .set(connection.minor(), newMinor)
  .commit(callback);

Updated to the 0.7 SDK, updated my code accordingly.
There’s still something strange going on.

While the callback event onSuccess does fire, my Activity code that would be managing the UI gets interrupted by the BluetoothGatt class.
Strange as that sounds, it’s the only thing I can say from debugging and stepping through it.

Before my activity can execute another line, code execution switches to the BluetoothGatt class, in either the onCharacteristicRead or onCharacteristicWrite method. My activity code is interrupted by this and doesn’t get a chance to alert the UI to the change in beacon values.

This looks like the same issue I was having before.

What do you mean that UI gets interrupted by BluetoothGatt class? Exception thrown and you can observe it in logs?

That’s the oddity. It doesn’t look like a thrown exception at all. The app doesn’t crash. I see no exception in debugger.

Stepping through the code, it starts on the activity code and then proceeds immediately to the BluetoothGatt class. And before it completes execution of either of the methods mentioned, it just stops and does not return to executing code on the activity.

I would test again right now to pull up something from the stack trace, but it seems that our app been removed from our Estimote Cloud account and the site won’t let me add a new app to generate a new App ID and Token.

EDIT: Something does seem to be happening with the Estimote Cloud at the moment. This will delay testing.

Please keep me posted. There might be temporal problems with Estimote Cloud.

If problem persists, I’ll create sample project to change uuid/major/minor, publish on GitHub and we can together look at it.

I’m coming back to this now that iOS has gotten stuck as well.

The app is currently failing to authenticate the beacon connection.
The onAuthenticationError method is fired correctly but I’m not getting any useful information out of the EstimoteDeviceException. No detail message and an Error code of -1.

Here are the last few lines of the stack trace if it helps.

"<1> main@830032695112" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
      at com.<company name>.<app name>.EstBeaconServices.EBeaconConnector$1.onAuthenticationError(EBeaconConnector.java:93)
      at com.estimote.sdk.connection.BeaconConnection$1.failure(BeaconConnection.java:178)
      at com.estimote.sdk.cloud.internal.InternalEstimoteCloud$4.failure(InternalEstimoteCloud.java:216)
      at com.estimote.sdk.repackaged.retrofit_v1_9_0.retrofit.CallbackRunnable$2.run(CallbackRunnable.java:53)

@heypiotr Can you help with iOS authentication? It looks SDK agnostic problem.

@Jon_PS Can you turn debug logs in Android SDK via EstimoteSDK.enableDebugLogging(true);?

I have Estimote debugging on.
I’m not terribly familiar with accessing logs in Android Studio though, but I’ll provide all the details I can.

Any news on what’s happening with the Estimote Cloud connection?

EDIT: So it looks like the Estimote Cloud problem is getting fixed, at least for the Android SDK.
The app can check the firmware fine.
But the original problem is still occurring. My activity’s code is interrupted by the BluetoothGatt class and doesn’t return.

Here is the code being stepped into

public void onCharacteristicRead(String address, int status, int srvcType,
                                 int srvcInstId, ParcelUuid srvcUuid,
                                 int charInstId, ParcelUuid charUuid, byte[] value)
{
   if (VDBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address
         + " UUID=" + charUuid + " Status=" + status);

   if (!address.equals(mDevice.getAddress()))
   {
      return;
   }

   synchronized (mDeviceBusy)
   {
      mDeviceBusy = false;
   }
<code continues>
....

Execution fails when it goes to the synchronized line.
The debugger shows this among the local variable values

mDeviceBusy : No such instance field: 'mDeviceBusy'

That’s the only red text I can see. No Error is thrown but, as I said, execution does not return to my activity’s code.

Bumping this topic because the issue still isn’t resolved.
Please see my previous comment.

I wonder if it could be that you have a deadlock on the mDeviceBusy. That could explain why the execution doesn’t return to your code, and also could explain BluetoothGatt preemptively taking over. Do you think it’s worth exploring?

@heypiotr
Today I ran a new batch of tests.

For most beacons everything seems to be working now. But I encountered issues on a few specific ones.

One beacon keeps giving an authentication error when attempting to check its firmware version.
c5b6aed78372

Another beacon hangs like I’ve mentioned in this thread and I have to manually timeout the update to keep the app from waiting forever on the SDK.
e88c01268f6d

Can you connect to it with the Estimote iOS app, or does it also give you trouble there?

I should have mentioned it before.
The beacon in question has no trouble connecting with the Estimote app on either iOS or Android.

To anyone who might be reading this in the future looking for answers to the same questions:

The issue also affected another feature and was resolved on another thread.

It seems the problem is that the callbacks are happening in a background thread. Attempting to update the UI from these callbacks causes problems.
Any UI updates from here need to be wrapped in a runOnUiThread call to make sure the instructions are executed on the main thread.

1 Like

Once again, thanks @Jon_PS for your help making SDK better!