0

I have an Asus P00A tablet (Android 7.0, API24) on which the BLE stops after some hours. (This affects any BLE app, not just my app using Android Beacon Library). Apps start working again if I manually switch off BLE then switch it back on.

The BluetoothMedic auto-fix system did not work for my tablet. It runs every 15 minutes but does not find a fault and so does not "power cycle" the Bluetooth. However, I hacked the BluetoothMedic class, adding this:

public void cycleBluetooth(Context context) {...}

and attached this to a button. I find this will restore BLE functionality. So I wondered what would happen if I unconditionally reset the BLE every 15 minutes. I added:

public static final int ALWAYS_RESET = 4;

and then call medic.enablePeriodicTests(context, BluetoothMedic.ALWAYS_RESET);

and add code inside BluetoothTestJob.onStartJob() which then calls BluetoothMedic.cycleBluetooth(). This behaves as expected and so far my app has run perfectly for 18 hours.

I am interested in any advice, such as:

1 Are there any tests other than the two in BluetoothMedic that I can run to detect that my tablet's Bluetooth has stopped? (I am happy to experiment).

2 Any comments on the hack I describe above? Should it be OK to unconditionally reset the Bluetooth every 15 minutes?

3 If the Bluetooth is reset ("power cycled") then is the rest of the Android Bluetooth Library OK with this? That is, will it carry on with monitoring and ranging that has been previously set up, or does the application code need to set take any action to get things going again? Note that this would apply to resets by the existing enablePowerCycleOnFailures() code as well as my ALWAYS_RESET hack above. (Maybe there are some crashes that could happen if the power cycling came at the wrong time?).

4 Could I suggest adding a callback so the application can learn if the Bluetooth has been cycled? Perhaps as a parameter to enablePowerCycleOnFailures()

5 I understand that background activities can be stopped by the OS, especially with Android 8. Would this also affect the regular 15 minute tests set up by enablePeriodicTests()?

Acutetech
  • 3
  • 3

1 Answers1

-1

The Android Beacon LIbrary's BluetoothMedic, as currently built, relies on the operating system's error code returned by a scan failure (or an advertising failure) to decide if the bluetooth stack is in a bad state warranting a power cycle.

For scans, if the onScanFailed callback is called with an error code of SCAN_FAILED_APPLICATION_REGISTRATION_FAILED which has the value of 2, the module considers it worthy of a power cycle..

For advertisements, if the onStartFailed callback is called with an error code of ADVERTISE_FAILED_INTERNAL_ERROR which has a value of 4, the module considers it worth of a power cycle..

These values were determined via experimentation, witnessing that on some devices, once an error callback is called with these values, bluetooth on the device would not work again without turning it off and back on. You can see the discussion of this in this thread.

You may want to see if there are other error codes on the Asus P00A that indicate a problem worthy of cycling bluetooth. To do this, wait for a failure, and see if attempts to start scanning call the onScanFailed callback with a distinct error code. If such error codes exist, this would be a better solution than cycling power to bluetooth regularly, as cycling power to bluetooth does break BLE GATT connections and the operation of bluetooth classic functions like speakers. The Android Beacon Library itself recovers from these power cycles just fine, although it will obviously not detect beacons until bluetooth is back on.

Because the BluetoothMedic uses the Android Job Scheduler for periodic tests, it is not affected by background limitations on Android 8+.

If you are interested in augmenting these functions in the library, please feel free to open an issue in the Github repo, and issue a Pull Request if you have code to share.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204