Repository: altbeacon/android-beacon-library
Issue: Switching from monitoring to ranging during active scan cycle breaks scanning

Hi David,

thanks for your work on this library! I've been using it for a while but I ran into a small issue lately.

So my app monitors beacons with a specific UUID and as soon as it receives a `didEnterRegion` callback, it stops monitoring and starts ranging that same UUID. The problem is that ranging stops within seconds after it has been started.

The relevant code basically looks like this:

``` java
    @Override
    public void didEnterRegion(Region region) {
        mBeaconManager.stopMonitoringBeaconsInRegion(region);
        mBeaconManager.startRangingBeaconsInRegion(region);
    }
```

I did some debugging and these are the steps that lead to the issue:
1. App calls `startMonitoringBeaconsInRegion()`
2. Starting monitoring calls `mCycledScanner.start()` which sets `mScanningEnabled=true` and calls `scanLeDevice(true)`
3. `scanLeDevice(true)` then sets `mScanCyclerStarted=true`, `mScanning=true` and starts a scan cycle
4. App calls `stopMonitoringBeaconsInRegion()`
5. Stopping monitoring calls `mCycledScanner.stop()` which sets `mScanningEnabled=false` and calls `scanLeDevice(false)`
6. `scanLeDevice(false)` then sets `mScanning=false`
7. App calls `startRangingBeaconsInRegion()`
8. Starting ranging calls `mCycledScanner.start()` which sets `mScanningEnabled=true` but does not call `scanLeDevice(true)` as `mScanCyclerStarted` is still `true`
9. At some point in the future `finishScanCycle()` is called as the scan cycle started earlier for monitoring ends
10. `finishScanCycle()` does nothing as `mScanning=false` and `mScanningEnabled=true`

At this point no new scan has been scheduled so scanning stops. It's also impossible to start a new scan as `mScanCyclerStarted=true` and this guards the call to `scanLeDevice(true)` in `start()`. `mScanCyclerStarted` is only reset to `false` in `finishScanCycle()` if `mScanning=true` and `mScanningEnabled=true`, which - if I'm not mistaken - can't be achieved in this situation. Looks like a deadlock.

A workaround for an app is waiting for the scan cycle to finish after calling `stopMonitoringBeaconsInRegion()` and only then call `startRangingBeaconsInRegion()`.

The device I observed this on was a Moto G (2nd gen) with Android 5.0.2 and AndroidLScanning disabled. Library version was 2.5.1.

This is the relevant debug log for reference:

```
          BeaconService  I  start monitoring received
                         D  startMonitoring called
                         D  Currently monitoring 1 regions.
        CycledLeScanner  D  start called
                         D  starting a new scan cycle
                         D  starting a new bluetooth le scan
                         D  Waiting to stop scan cycle for another 1100 milliseconds
                         D  Scan started
                         D  Set scan periods called with 2500, 500 Background mode must have changed.
                         D  We are not in the background.  Cancelling wakeup alarm
                         D  cancel wakeup alarm: null
eScannerForJellyBeanMr2  D  got record
                         D  got record
           BeaconParser  D  Ignoring pdu type 01
                         D  Processing pdu type FF: 02010617ff4c000512000000000000000001b11468c100000000000000000000000000000000000000000000000000000000000000000000000000000000 with startIndex: 5, endIndex: 26
                         D  This is not a matching Beacon advertisement. (Was expecting 02 15.  The bytes I see are: 02010617ff4c000512000000000000000001b11468c100000000000000000000000000000000000000000000000000000000000000000000000000000000
                         D  Ignoring pdu type 01
                         D  Processing pdu type FF: 02011a17ff4c000512000000000000000001b11468c1000000000014ff4c0001000000000000000000000004000000000000000000000000000000000000 with startIndex: 5, endIndex: 26
                         D  This is not a matching Beacon advertisement. (Was expecting 02 15.  The bytes I see are: 02011a17ff4c000512000000000000000001b11468c1000000000014ff4c0001000000000000000000000004000000000000000000000000000000000000
        CycledLeScanner  D  Waiting to stop scan cycle for another 98 milliseconds
                         D  Done with scan cycle
                         D  stopping bluetooth le scan
                         D  Normalizing between scan period from 500 to -1781
                         D  starting a new scan cycle
                         D  starting a new bluetooth le scan
                         D  Waiting to stop scan cycle for another 2500 milliseconds
                            [...]
eScannerForJellyBeanMr2  D  got record
           BeaconParser  D  Ignoring pdu type 01
                         D  Processing pdu type FF: 0201061aff4c000215xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx02d2920cc609095069426561636f6e00000000000000000000000000000000000000000000 with startIndex: 5, endIndex: 29
                         D  This is a recognized beacon advertisement -- 02 15 seen
          BeaconService  D  beacon detected : id1: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx id2: 722 id3: 37388
  BeaconIntentProcessor  D  got an intent to process
                         D  got monitoring data
                         D  Calling monitoring notifier: com.dummy.MyBeaconManager@227351d4
          BeaconManager  D  callback packageName: com.dummy
          BeaconService  I  stop monitoring received
                         D  stopMonitoring called
                         D  Currently monitoring 0 regions.
        CycledLeScanner  D  stop called
                         D  disabling scan
                         D  Set scan periods called with 2500, 500 Background mode must have changed.
                         D  We are not in the background.  Cancelling wakeup alarm
                         D  cancel wakeup alarm: PendingIntent{7b19601: android.os.BinderProxy@28175ca6}
                         D  Set a wakeup alarm to go off in 9223372036854775807 ms: PendingIntent{7b19601: android.os.BinderProxy@28175ca6}
tartupBroadcastReceiver  D  onReceive called in startup broadcast receiver
                         D  got wake up intent
          BeaconManager  D  callback packageName: com.dummy
          BeaconService  I  start ranging received
                         D  Currently ranging 1 regions.
        CycledLeScanner  D  start called
                         D  scanning already started
                         D  Set scan periods called with 2500, 500 Background mode must have changed.
                         D  We are not in the background.  Cancelling wakeup alarm
                         D  cancel wakeup alarm: PendingIntent{7b19601: android.os.BinderProxy@28175ca6}
                         D  Set a wakeup alarm to go off in 9223372036854775807 ms: PendingIntent{7b19601: android.os.BinderProxy@28175ca6}
tartupBroadcastReceiver  D  onReceive called in startup broadcast receiver
                         D  got wake up intent
          BeaconService  D  looking for ranging region matches for this beacon
                         D  matches ranging region: id1: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx id2: null id3: null
             RangeState  D  adding id1: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx id2: 722 id3: 37388 to new rangedBeacon
        CycledLeScanner  D  Waiting to stop scan cycle for another 1500 milliseconds
                         D  Waiting to stop scan cycle for another 498 milliseconds
                         D  Done with scan cycle
          BeaconService  D  Calling ranging callback
unningAverageRssiFilter  D  Running average mRssi based on 1 measurements: -67.0
           RangedBeacon  D  calculated new runningAverageRssi: -67.0
            RangingData  D  writing RangingData
                 Beacon  D  serializing identifiers of size 3
ittedDistanceCalculator  D  calculating distance based on mRssi of -67.0 and txPower of -58
                         D  avg mRssi: -67.0 distance: 1.6966333022995579
                 Beacon  D  writing 0 extra data fields to parcel
            RangingData  D  done writing RangingData
  BeaconIntentProcessor  D  got an intent to process
            RangingData  D  parsing RangingData
                 Beacon  D  reading 0 extra data fields from parcel
            RangingData  D  parsing RangingData
                 Beacon  D  reading 0 extra data fields from parcel
  BeaconIntentProcessor  D  got ranging data
                 Beacon  D  Not using running average RSSI because it is null
ittedDistanceCalculator  D  calculating distance based on mRssi of -67.0 and txPower of -58
                         D  avg mRssi: -67.0 distance: 1.6966333022995579
```


Changed files:
src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScanner.java

diff --git a/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScanner.java b/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScanner.java
index 573981b..e228de8 100644
--- a/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScanner.java
+++ b/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScanner.java
@@ -208,7 +208,7 @@ public abstract class CycledLeScanner {
         } else {
             LogManager.d(TAG, "disabling scan");
             mScanning = false;
-
+            mScanCyclerStarted = false;
             stopScan();
             mLastScanCycleEndTime = new Date().getTime();
         }