private void scanLeDevice(final Boolean enable) {
    if (getBluetoothAdapter() == null) {
      Log.e(TAG, "no bluetooth adapter.  I cannot scan.");
      if (simulatedScanData == null) {
        Log.w(TAG, "exiting");
        return;
      } else {
        Log.w(TAG, "proceeding with simulated scan data");
      }
    }
    if (enable) {
      long millisecondsUntilStart = nextScanStartTime - (new Date().getTime());
      if (millisecondsUntilStart > 0) {
        Log.d(
            TAG,
            "Waiting to start next bluetooth scan for another "
                + millisecondsUntilStart
                + " milliseconds");
        // Don't actually wait until the next scan time -- only wait up to 1 second.  this
        // allows us to start scanning sooner if a consumer enters the foreground and expects
        // results more quickly
        handler.postDelayed(
            new Runnable() {
              @Override
              public void run() {
                scanLeDevice(true);
              }
            },
            millisecondsUntilStart > 1000 ? 1000 : millisecondsUntilStart);
        return;
      }

      trackedBeacons = new HashSet<IBeacon>();
      if (scanning == false || scanningPaused == true) {
        scanning = true;
        scanningPaused = false;
        try {
          if (getBluetoothAdapter() != null) {
            if (getBluetoothAdapter().isEnabled()) {
              getBluetoothAdapter().startLeScan(leScanCallback);
              lastScanStartTime = new Date().getTime();
            } else {
              Log.w(TAG, "Bluetooth is disabled.  Cannot scan for iBeacons.");
            }
          }
        } catch (Exception e) {
          Log.e(
              "TAG",
              "Exception starting bluetooth scan.  Perhaps bluetooth is disabled or unavailable?");
        }
      } else {
        Log.d(TAG, "We are already scanning");
      }
      scanStopTime = (new Date().getTime() + scanPeriod);
      scheduleScanStop();

      Log.d(TAG, "Scan started");
    } else {
      Log.d(TAG, "disabling scan");
      scanning = false;
      if (getBluetoothAdapter() != null) {
        getBluetoothAdapter().stopLeScan(leScanCallback);
        lastScanEndTime = new Date().getTime();
      }
    }
  }
  @TargetApi(18)
  private void scanLeDevice(final Boolean enable) {
    scanCyclerStarted = true;
    if (android.os.Build.VERSION.SDK_INT < 18) {
      Log.w(TAG, "Not supported prior to API 18.");
      return;
    }
    if (getBluetoothAdapter() == null) {
      Log.e(TAG, "No bluetooth adapter.  iBeaconService cannot scan.");
      if (simulatedScanData == null) {
        Log.w(TAG, "exiting");
        return;
      } else {
        Log.w(TAG, "proceeding with simulated scan data");
      }
    }
    if (enable) {
      long millisecondsUntilStart = nextScanStartTime - (new Date().getTime());
      if (millisecondsUntilStart > 0) {
        if (IBeaconManager.LOG_DEBUG)
          Log.d(
              TAG,
              "Waiting to start next bluetooth scan for another "
                  + millisecondsUntilStart
                  + " milliseconds");
        // Don't actually wait until the next scan time -- only wait up to 1 second.  this
        // allows us to start scanning sooner if a consumer enters the foreground and expects
        // results more quickly
        handler.postDelayed(
            new Runnable() {
              @Override
              public void run() {
                scanLeDevice(true);
              }
            },
            millisecondsUntilStart > 1000 ? 1000 : millisecondsUntilStart);
        return;
      }

      trackedBeacons = new HashSet<IBeacon>();
      trackedBeaconsPacketCount = 0;
      if (scanning == false || scanningPaused == true) {
        scanning = true;
        scanningPaused = false;
        try {
          if (getBluetoothAdapter() != null) {
            if (getBluetoothAdapter().isEnabled()) {
              if (bluetoothCrashResolver.isRecoveryInProgress()) {
                Log.w(TAG, "Skipping scan because crash recovery is in progress.");
              } else {
                if (scanningEnabled) {
                  getBluetoothAdapter()
                      .startLeScan((BluetoothAdapter.LeScanCallback) getLeScanCallback());
                } else {
                  if (IBeaconManager.LOG_DEBUG)
                    Log.d(TAG, "Scanning unnecessary - no monitoring or ranging active.");
                }
              }
              lastScanStartTime = new Date().getTime();
            } else {
              Log.w(TAG, "Bluetooth is disabled.  Cannot scan for iBeacons.");
            }
          }
        } catch (Exception e) {
          Log.e(
              "TAG",
              "Exception starting bluetooth scan.  Perhaps bluetooth is disabled or unavailable?");
        }
      } else {
        if (IBeaconManager.LOG_DEBUG) Log.d(TAG, "We are already scanning");
      }
      scanStopTime = (new Date().getTime() + scanPeriod);
      scheduleScanStop();

      if (IBeaconManager.LOG_DEBUG) Log.d(TAG, "Scan started");
    } else {
      if (IBeaconManager.LOG_DEBUG) Log.d(TAG, "disabling scan");
      scanning = false;
      if (getBluetoothAdapter() != null) {
        getBluetoothAdapter().stopLeScan((BluetoothAdapter.LeScanCallback) getLeScanCallback());
        lastScanEndTime = new Date().getTime();
      }
    }
  }